Thing is an Object subclass with description, portable flag, and aliases. Entity.can_accept() returns True for portable Things, enabling the containment model where entities carry items in their contents.
117 lines
3.5 KiB
Python
117 lines
3.5 KiB
Python
"""Tests for the Thing class."""
|
|
|
|
from mudlib.entity import Entity
|
|
from mudlib.object import Object
|
|
from mudlib.thing import Thing
|
|
from mudlib.zone import Zone
|
|
|
|
|
|
# --- construction ---
|
|
|
|
|
|
def test_thing_creation_minimal():
|
|
"""Thing can be created with just a name."""
|
|
t = Thing(name="rock")
|
|
assert t.name == "rock"
|
|
assert t.location is None
|
|
assert t.description == ""
|
|
assert t.portable is True # default: things are portable
|
|
|
|
|
|
def test_thing_creation_with_description():
|
|
"""Thing can have a description."""
|
|
t = Thing(name="sword", description="a rusty iron sword")
|
|
assert t.description == "a rusty iron sword"
|
|
|
|
|
|
def test_thing_creation_non_portable():
|
|
"""Thing can be marked as non-portable (fixture, scenery)."""
|
|
t = Thing(name="fountain", portable=False)
|
|
assert t.portable is False
|
|
|
|
|
|
def test_thing_in_zone():
|
|
"""Thing can be placed in a zone with coordinates."""
|
|
terrain = [["." for _ in range(10)] for _ in range(10)]
|
|
zone = Zone(name="test", width=10, height=10, terrain=terrain)
|
|
rock = Thing(name="rock", location=zone, x=3, y=7)
|
|
assert rock.location is zone
|
|
assert rock.x == 3
|
|
assert rock.y == 7
|
|
assert rock in zone.contents
|
|
|
|
|
|
def test_thing_in_entity_inventory():
|
|
"""Thing can be placed in an entity (inventory)."""
|
|
terrain = [["." for _ in range(10)] for _ in range(10)]
|
|
zone = Zone(name="test", width=10, height=10, terrain=terrain)
|
|
entity = Entity(name="player", location=zone, x=5, y=5)
|
|
sword = Thing(name="sword", location=entity)
|
|
assert sword.location is entity
|
|
assert sword in entity.contents
|
|
# Inventory items don't need coordinates
|
|
assert sword.x is None
|
|
assert sword.y is None
|
|
|
|
|
|
def test_thing_is_subclass_of_object():
|
|
"""Thing inherits from Object."""
|
|
t = Thing(name="gem")
|
|
assert isinstance(t, Object)
|
|
|
|
|
|
def test_thing_aliases_default_empty():
|
|
"""Thing aliases default to empty list."""
|
|
t = Thing(name="rock")
|
|
assert t.aliases == []
|
|
|
|
|
|
def test_thing_aliases():
|
|
"""Thing can have aliases for matching."""
|
|
t = Thing(name="pepsi can", aliases=["can", "pepsi"])
|
|
assert t.aliases == ["can", "pepsi"]
|
|
|
|
|
|
# --- entity.can_accept ---
|
|
|
|
|
|
def test_entity_can_accept_portable_thing():
|
|
"""Entity accepts portable things (inventory)."""
|
|
entity = Entity(name="player")
|
|
sword = Thing(name="sword", portable=True)
|
|
assert entity.can_accept(sword) is True
|
|
|
|
|
|
def test_entity_rejects_non_portable_thing():
|
|
"""Entity rejects non-portable things."""
|
|
entity = Entity(name="player")
|
|
fountain = Thing(name="fountain", portable=False)
|
|
assert entity.can_accept(fountain) is False
|
|
|
|
|
|
def test_entity_rejects_non_thing():
|
|
"""Entity rejects objects that aren't Things."""
|
|
entity = Entity(name="player")
|
|
other = Object(name="abstract")
|
|
assert entity.can_accept(other) is False
|
|
|
|
|
|
# --- zone interaction ---
|
|
|
|
|
|
def test_zone_contents_at_finds_things():
|
|
"""Zone.contents_at finds things at a position."""
|
|
terrain = [["." for _ in range(10)] for _ in range(10)]
|
|
zone = Zone(name="test", width=10, height=10, terrain=terrain)
|
|
rock = Thing(name="rock", location=zone, x=5, y=5)
|
|
result = zone.contents_at(5, 5)
|
|
assert rock in result
|
|
|
|
|
|
def test_zone_contents_near_finds_things():
|
|
"""Zone.contents_near finds things within range."""
|
|
terrain = [["." for _ in range(10)] for _ in range(10)]
|
|
zone = Zone(name="test", width=10, height=10, terrain=terrain)
|
|
rock = Thing(name="rock", location=zone, x=5, y=5)
|
|
result = zone.contents_near(5, 5, 3)
|
|
assert rock in result
|