Implements a global examine/ex command that shows detailed descriptions of objects. Searches inventory first, then ground at player position. Works with Things, Containers, and Mobs.
206 lines
5.4 KiB
Python
206 lines
5.4 KiB
Python
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from mudlib.commands.examine import cmd_examine
|
|
from mudlib.container import Container
|
|
from mudlib.entity import Mob
|
|
from mudlib.player import Player
|
|
from mudlib.thing import Thing
|
|
from mudlib.zone import Zone
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_writer():
|
|
writer = MagicMock()
|
|
writer.write = MagicMock()
|
|
writer.drain = AsyncMock()
|
|
return writer
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_reader():
|
|
return MagicMock()
|
|
|
|
|
|
@pytest.fixture
|
|
def test_zone():
|
|
terrain = [["." for _ in range(10)] for _ in range(10)]
|
|
return Zone(name="testzone", width=10, height=10, terrain=terrain)
|
|
|
|
|
|
@pytest.fixture
|
|
def player(mock_reader, mock_writer, test_zone):
|
|
return Player(
|
|
name="TestPlayer",
|
|
x=5,
|
|
y=5,
|
|
reader=mock_reader,
|
|
writer=mock_writer,
|
|
location=test_zone,
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_no_args(player, mock_writer):
|
|
"""examine with no args prompts what to examine"""
|
|
await cmd_examine(player, "")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "Examine what?" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_thing_on_ground_by_name(player, test_zone, mock_writer):
|
|
"""examine finds Thing on ground by name and shows description"""
|
|
_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="A smooth gray rock with moss on one side.",
|
|
)
|
|
|
|
await cmd_examine(player, "rock")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A smooth gray rock with moss on one side." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_thing_on_ground_by_alias(player, test_zone, mock_writer):
|
|
"""examine finds Thing on ground by alias"""
|
|
_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
aliases=["stone"],
|
|
description="A smooth gray rock.",
|
|
)
|
|
|
|
await cmd_examine(player, "stone")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A smooth gray rock." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_thing_in_inventory_by_name(player, test_zone, mock_writer):
|
|
"""examine finds Thing in inventory by name"""
|
|
_key = Thing(
|
|
name="key",
|
|
x=5,
|
|
y=5,
|
|
location=player,
|
|
description="A rusty iron key.",
|
|
)
|
|
|
|
await cmd_examine(player, "key")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A rusty iron key." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_inventory_before_ground(player, test_zone, mock_writer):
|
|
"""examine finds in inventory before ground"""
|
|
_ground_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="A rock on the ground.",
|
|
)
|
|
_inventory_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=player,
|
|
description="A rock in your pocket.",
|
|
)
|
|
|
|
await cmd_examine(player, "rock")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A rock in your pocket." in output
|
|
assert "A rock on the ground." not in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_mob_at_position(player, test_zone, mock_writer):
|
|
"""examine finds Mob at same position and shows description"""
|
|
_goblin = Mob(
|
|
name="goblin",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="A small, greenish creature with beady eyes.",
|
|
)
|
|
|
|
await cmd_examine(player, "goblin")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A small, greenish creature with beady eyes." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_not_found(player, mock_writer):
|
|
"""examine nonexistent object shows not found message"""
|
|
await cmd_examine(player, "flurb")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "You don't see that here." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_thing_with_empty_description(player, test_zone, mock_writer):
|
|
"""examine thing with empty description shows default message"""
|
|
_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="",
|
|
)
|
|
|
|
await cmd_examine(player, "rock")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "You see nothing special." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_container_shows_description(player, test_zone, mock_writer):
|
|
"""examine Container shows description"""
|
|
_chest = Container(
|
|
name="chest",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="A sturdy wooden chest with brass hinges.",
|
|
closed=False,
|
|
)
|
|
|
|
await cmd_examine(player, "chest")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A sturdy wooden chest with brass hinges." in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_examine_alias_ex(player, test_zone, mock_writer):
|
|
"""ex alias works"""
|
|
_rock = Thing(
|
|
name="rock",
|
|
x=5,
|
|
y=5,
|
|
location=test_zone,
|
|
description="A smooth rock.",
|
|
)
|
|
|
|
# The command registration will handle the alias, but test function
|
|
await cmd_examine(player, "rock")
|
|
|
|
output = "".join(call[0][0] for call in mock_writer.write.call_args_list)
|
|
assert "A smooth rock." in output
|