144 lines
4.3 KiB
Python
144 lines
4.3 KiB
Python
"""Tests for the commands listing command."""
|
|
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from mudlib import commands
|
|
|
|
# Import command modules to register their commands
|
|
from mudlib.commands import (
|
|
edit, # noqa: F401
|
|
fly, # noqa: F401
|
|
help, # noqa: F401
|
|
look, # noqa: F401
|
|
movement, # noqa: F401
|
|
quit, # noqa: F401
|
|
)
|
|
|
|
|
|
@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 player(mock_reader, mock_writer):
|
|
from mudlib.player import Player
|
|
|
|
return Player(
|
|
name="TestPlayer",
|
|
x=5,
|
|
y=5,
|
|
reader=mock_reader,
|
|
writer=mock_writer,
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_command_exists():
|
|
"""Test that commands command is registered."""
|
|
assert "commands" in commands._registry
|
|
assert "cmds" in commands._registry
|
|
assert commands._registry["commands"] is commands._registry["cmds"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_has_wildcard_mode():
|
|
"""Test that commands works from any mode."""
|
|
assert commands._registry["commands"].mode == "*"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_lists_all_commands(player):
|
|
"""Test that commands command lists all unique commands."""
|
|
# Execute the command
|
|
await commands.dispatch(player, "commands")
|
|
|
|
# Collect all output
|
|
output = "".join([call[0][0] for call in player.writer.write.call_args_list])
|
|
|
|
# Should contain at least movement and other groups
|
|
assert "Movement:" in output
|
|
assert "Other:" in output
|
|
|
|
# Should show some specific commands with their primary names
|
|
assert "north" in output
|
|
assert "look" in output
|
|
assert "quit" in output
|
|
assert "commands" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_shows_aliases(player):
|
|
"""Test that aliases are shown in parens after command names."""
|
|
await commands.dispatch(player, "commands")
|
|
output = "".join([call[0][0] for call in player.writer.write.call_args_list])
|
|
|
|
# Check that some aliases are shown in parentheses
|
|
assert "north(n)" in output or "north (n)" in output
|
|
assert "look(l)" in output or "look (l)" in output
|
|
assert "quit(q)" in output or "quit (q)" in output
|
|
assert "commands(cmds)" in output or "commands (cmds)" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_deduplicates_entries(player):
|
|
"""Test that aliases don't create duplicate command entries."""
|
|
await commands.dispatch(player, "commands")
|
|
output = "".join([call[0][0] for call in player.writer.write.call_args_list])
|
|
|
|
# Count how many times "north" appears as a primary command
|
|
# It should appear once in the movement group, not multiple times
|
|
# (Note: it might appear in parens as part of another command, but
|
|
# we're checking it doesn't appear as a standalone entry multiple times)
|
|
lines_with_north_command = [
|
|
line for line in output.split("\n") if line.strip().startswith("north")
|
|
]
|
|
# Should only have one line starting with "north" as a command
|
|
assert len(lines_with_north_command) <= 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_groups_correctly(player):
|
|
"""Test that commands are grouped by type."""
|
|
await commands.dispatch(player, "commands")
|
|
output = "".join([call[0][0] for call in player.writer.write.call_args_list])
|
|
|
|
# Find the groups
|
|
movement_pos = output.find("Movement:")
|
|
other_pos = output.find("Other:")
|
|
|
|
# At minimum, movement and other should exist
|
|
assert movement_pos != -1
|
|
assert other_pos != -1
|
|
|
|
# Check that movement commands appear in the movement section
|
|
# (before the "Other:" section)
|
|
movement_section = output[movement_pos:other_pos]
|
|
assert "north" in movement_section
|
|
assert "east" in movement_section
|
|
|
|
# Check that non-movement commands appear in other section
|
|
other_section = output[other_pos:]
|
|
assert "quit" in other_section
|
|
assert "look" in other_section
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_commands_via_alias(player):
|
|
"""Test that the cmds alias works."""
|
|
await commands.dispatch(player, "cmds")
|
|
output = "".join([call[0][0] for call in player.writer.write.call_args_list])
|
|
|
|
# Should produce the same output structure
|
|
assert "Movement:" in output
|
|
assert "Other:" in output
|