"""Tests for the Container class.""" import pytest from mudlib.container import Container from mudlib.object import Object from mudlib.player import Player from mudlib.thing import Thing from mudlib.zone import Zone # --- fixtures --- @pytest.fixture def test_zone(): terrain = [["." for _ in range(10)] for _ in range(10)] return Zone( name="testzone", width=10, height=10, toroidal=True, terrain=terrain, ) @pytest.fixture def player(mock_reader, mock_writer, test_zone): p = Player( name="TestPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer, location=test_zone, ) return p # --- construction --- # --- can_accept --- def test_container_accepts_thing_when_open(): """Container accepts Things when open and has capacity.""" c = Container(name="chest") sword = Thing(name="sword") assert c.can_accept(sword) is True def test_container_rejects_when_closed(): """Container rejects Things when closed.""" c = Container(name="chest", closed=True) sword = Thing(name="sword") assert c.can_accept(sword) is False def test_container_rejects_when_at_capacity(): """Container rejects Things when at capacity.""" c = Container(name="pouch", capacity=2) # Add two items Thing(name="rock1", location=c) Thing(name="rock2", location=c) # Third should be rejected rock3 = Thing(name="rock3") assert c.can_accept(rock3) is False def test_container_accepts_when_below_capacity(): """Container accepts Things when below capacity.""" c = Container(name="pouch", capacity=2) Thing(name="rock1", location=c) # Second item should be accepted rock2 = Thing(name="rock2") assert c.can_accept(rock2) is True def test_container_rejects_non_thing(): """Container rejects objects that aren't Things.""" c = Container(name="chest") other = Object(name="abstract") assert c.can_accept(other) is False def test_container_locked_is_just_flag(): """Locked flag is stored but doesn't affect can_accept (used by commands).""" c = Container(name="chest", locked=True, closed=False) sword = Thing(name="sword") # can_accept doesn't check locked (commands will check it separately) # This test documents current behavior — locked is for command layer assert c.locked is True # can_accept only checks closed and capacity assert c.can_accept(sword) is True # --- integration with zones --- def test_container_in_zone(): """Container 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) chest = Container(name="chest", location=zone, x=5, y=5) assert chest.location is zone assert chest.x == 5 assert chest.y == 5 assert chest in zone.contents def test_container_with_contents(): """Container can hold Things.""" chest = Container(name="chest") sword = Thing(name="sword", location=chest) gem = Thing(name="gem", location=chest) assert sword in chest.contents assert gem in chest.contents assert len(chest.contents) == 2 # --- look command container display --- @pytest.mark.asyncio async def test_look_shows_closed_container(player, test_zone, mock_writer): """look shows closed containers with (closed) suffix.""" from mudlib.commands.look import cmd_look Container(name="chest", location=test_zone, x=5, y=5, closed=True) await cmd_look(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "chest (closed)" in output @pytest.mark.asyncio async def test_look_shows_open_empty_container(player, test_zone, mock_writer): """look shows open empty containers with (open, empty) suffix.""" from mudlib.commands.look import cmd_look Container(name="chest", location=test_zone, x=5, y=5, closed=False) await cmd_look(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "chest (open, empty)" in output @pytest.mark.asyncio async def test_look_shows_open_container_with_contents(player, test_zone, mock_writer): """look shows open containers with their contents.""" from mudlib.commands.look import cmd_look chest = Container(name="chest", location=test_zone, x=5, y=5, closed=False) Thing(name="rock", location=chest) Thing(name="coin", location=chest) await cmd_look(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "chest (open, containing: rock, coin)" in output @pytest.mark.asyncio async def test_look_shows_regular_things_unchanged(player, test_zone, mock_writer): """look shows regular Things without container suffixes.""" from mudlib.commands.look import cmd_look Thing(name="rock", location=test_zone, x=5, y=5) await cmd_look(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "On the ground: rock" in output assert "(closed)" not in output assert "(open" not in output # --- inventory command container display --- @pytest.mark.asyncio async def test_inventory_shows_closed_container(player, mock_writer): """inventory shows closed containers with (closed) suffix.""" from mudlib.commands.things import cmd_inventory Container(name="sack", location=player, closed=True) await cmd_inventory(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "sack (closed)" in output @pytest.mark.asyncio async def test_inventory_shows_open_empty_container(player, mock_writer): """inventory shows open empty containers with (open, empty) suffix.""" from mudlib.commands.things import cmd_inventory Container(name="sack", location=player, closed=False) await cmd_inventory(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "sack (open, empty)" in output @pytest.mark.asyncio async def test_inventory_shows_container_with_contents(player, mock_writer): """inventory shows open containers with their contents.""" from mudlib.commands.things import cmd_inventory sack = Container(name="sack", location=player, closed=False) Thing(name="rock", location=sack) Thing(name="gem", location=sack) await cmd_inventory(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert "sack (open, containing: rock, gem)" in output @pytest.mark.asyncio async def test_inventory_shows_regular_things_unchanged(player, mock_writer): """inventory shows regular Things without container suffixes.""" from mudlib.commands.things import cmd_inventory Thing(name="rock", location=player) await cmd_inventory(player, "") output = "".join(call[0][0] for call in mock_writer.write.call_args_list) assert " rock\r\n" in output assert "(closed)" not in output assert "(open" not in output