Add character creation flow with description prompt
This commit is contained in:
parent
0f3ae87f33
commit
1c22530be7
2 changed files with 132 additions and 0 deletions
36
src/mudlib/creation.py
Normal file
36
src/mudlib/creation.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""Character creation flow for new players."""
|
||||
|
||||
|
||||
async def character_creation(
|
||||
name: str,
|
||||
read_func,
|
||||
write_func,
|
||||
) -> dict:
|
||||
"""Run character creation prompts for a new player.
|
||||
|
||||
Args:
|
||||
name: Player name
|
||||
read_func: Async function to read a line of input (returns str or None)
|
||||
write_func: Async function to write output
|
||||
|
||||
Returns:
|
||||
Dict with creation data: {"description": str}
|
||||
"""
|
||||
await write_func("\r\n--- Character Creation ---\r\n\r\n")
|
||||
await write_func(
|
||||
"Describe yourself in a short sentence or two.\r\n"
|
||||
"(This is what others see when they look at you.)\r\n\r\n"
|
||||
)
|
||||
await write_func("Description: ")
|
||||
|
||||
desc_input = await read_func()
|
||||
description = ""
|
||||
if desc_input is not None:
|
||||
description = desc_input.strip()
|
||||
|
||||
if description:
|
||||
await write_func(f'\r\nYou will be known as: "{description}"\r\n')
|
||||
else:
|
||||
await write_func("\r\nNo description set. You can change it later.\r\n")
|
||||
|
||||
return {"description": description}
|
||||
96
tests/test_creation.py
Normal file
96
tests/test_creation.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
"""Tests for character creation flow."""
|
||||
|
||||
from collections import deque
|
||||
|
||||
import pytest
|
||||
|
||||
from mudlib.creation import character_creation
|
||||
|
||||
|
||||
async def make_io(inputs):
|
||||
"""Create mock read/write functions."""
|
||||
input_queue = deque(inputs)
|
||||
output = []
|
||||
|
||||
async def read_func():
|
||||
if input_queue:
|
||||
return input_queue.popleft()
|
||||
return None
|
||||
|
||||
async def write_func(msg):
|
||||
output.append(msg)
|
||||
|
||||
return read_func, write_func, output
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_with_description():
|
||||
"""Test providing a description returns it."""
|
||||
read_func, write_func, output = await make_io(
|
||||
["A wandering swordsman with a mysterious past."]
|
||||
)
|
||||
|
||||
result = await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
assert result["description"] == "A wandering swordsman with a mysterious past."
|
||||
assert any("Character Creation" in msg for msg in output)
|
||||
assert any("Description:" in msg for msg in output)
|
||||
assert any("A wandering swordsman with a mysterious past." in msg for msg in output)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_empty_input():
|
||||
"""Test empty input returns empty string."""
|
||||
read_func, write_func, output = await make_io([""])
|
||||
|
||||
result = await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
assert result["description"] == ""
|
||||
assert any("No description set" in msg for msg in output)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_none_input():
|
||||
"""Test None input (disconnect) returns empty string."""
|
||||
read_func, write_func, output = await make_io([None])
|
||||
|
||||
result = await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
assert result["description"] == ""
|
||||
assert any("No description set" in msg for msg in output)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_prompts():
|
||||
"""Test the output includes the prompts."""
|
||||
read_func, write_func, output = await make_io(["Test description"])
|
||||
|
||||
await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
output_text = "".join(output)
|
||||
assert "Character Creation" in output_text
|
||||
assert "Describe yourself" in output_text
|
||||
assert "This is what others see when they look at you" in output_text
|
||||
assert "Description:" in output_text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_confirmation():
|
||||
"""Test the confirmation message includes the description."""
|
||||
read_func, write_func, output = await make_io(["A fierce warrior"])
|
||||
|
||||
await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
output_text = "".join(output)
|
||||
assert "You will be known as:" in output_text
|
||||
assert "A fierce warrior" in output_text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_character_creation_strips_whitespace():
|
||||
"""Test that leading/trailing whitespace is stripped."""
|
||||
read_func, write_func, output = await make_io([" A nimble thief "])
|
||||
|
||||
result = await character_creation("TestPlayer", read_func, write_func)
|
||||
|
||||
assert result["description"] == "A nimble thief"
|
||||
Loading…
Reference in a new issue