mud/tests/test_if_mode.py
Jared Miller 9c480f8d47
Remove duplicate mock_writer/mock_reader fixtures
Removed identical local copies from 45 test files. These fixtures
are already defined in conftest.py.
2026-02-16 15:29:21 -05:00

108 lines
3.4 KiB
Python

"""Tests for IF mode integration with player model and server shell."""
from unittest.mock import AsyncMock, MagicMock
import pytest
from mudlib.if_session import IFResponse, IFSession
from mudlib.player import Player
@pytest.fixture
def player(mock_reader, mock_writer):
return Player(name="TestPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer)
def test_player_has_if_session_attribute(player):
"""Player has if_session attribute that defaults to None."""
assert hasattr(player, "if_session")
assert player.if_session is None
def test_player_if_session_can_be_set(player):
"""Player.if_session can be set to an IFSession instance."""
session = IFSession(player, "/path/to/story.z5", "story")
player.if_session = session
assert player.if_session == session
@pytest.mark.asyncio
async def test_if_mode_routes_input_to_if_session(player):
"""Input routes to if_session.handle_input in IF mode."""
# Create a mock IF session
mock_session = MagicMock()
mock_session.handle_input = AsyncMock(
return_value=IFResponse(output="You see a room.\r\n", done=False)
)
player.if_session = mock_session
player.mode_stack.append("if")
# Simulate input routing (what shell loop should do)
if player.mode == "if" and player.if_session:
response = await player.if_session.handle_input("look")
assert response.output == "You see a room.\r\n"
assert response.done is False
mock_session.handle_input.assert_called_once_with("look")
@pytest.mark.asyncio
async def test_if_mode_done_clears_session_and_pops_mode(player):
"""When handle_input returns done=True, mode pops and if_session is cleared."""
# Create a mock IF session that returns done=True
mock_session = MagicMock()
mock_session.handle_input = AsyncMock(
return_value=IFResponse(output="Goodbye.\r\n", done=True)
)
mock_session.stop = AsyncMock()
player.if_session = mock_session
player.mode_stack.append("if")
# Simulate shell loop handling done response
if player.mode == "if" and player.if_session:
response = await player.if_session.handle_input("::quit")
if response.done:
await player.if_session.stop()
player.if_session = None
player.mode_stack.pop()
assert player.mode == "normal"
assert player.if_session is None
mock_session.stop.assert_called_once()
@pytest.mark.asyncio
async def test_mode_stack_push_and_pop_for_if(player):
"""Test mode stack mechanics for IF mode."""
assert player.mode_stack == ["normal"]
assert player.mode == "normal"
# Enter IF mode
player.mode_stack.append("if")
assert player.mode == "if"
assert player.mode_stack == ["normal", "if"]
# Exit IF mode
player.mode_stack.pop()
assert player.mode == "normal"
assert player.mode_stack == ["normal"]
@pytest.mark.asyncio
async def test_empty_input_allowed_in_if_mode(player):
"""Empty input is allowed in IF mode."""
# Create a mock IF session
mock_session = MagicMock()
mock_session.handle_input = AsyncMock(
return_value=IFResponse(output="Time passes.\r\n", done=False)
)
player.if_session = mock_session
player.mode_stack.append("if")
# Empty input should still be passed to IF session
response = await player.if_session.handle_input("")
assert response.output == "Time passes.\r\n"
mock_session.handle_input.assert_called_once_with("")