Removed identical local copies from 45 test files. These fixtures are already defined in conftest.py.
108 lines
3.4 KiB
Python
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("")
|