mud/tests/test_zone_export.py

322 lines
8.7 KiB
Python

"""Tests for zone export to TOML files."""
import pathlib
import tempfile
from mudlib.export import export_zone, export_zone_to_file
from mudlib.portal import Portal
from mudlib.zone import SpawnRule, Zone
from mudlib.zones import load_zone
def test_export_basic_zone():
"""Export a simple zone and verify TOML output has correct fields."""
zone = Zone(
name="test_zone",
width=4,
height=3,
toroidal=False,
terrain=[
["#", "#", "#", "#"],
["#", ".", ".", "#"],
["#", "#", "#", "#"],
],
impassable={"#"},
spawn_x=0,
spawn_y=0,
)
# Set description as an attribute (zones loaded from TOML have this)
zone.description = "a test zone"
toml_str = export_zone(zone)
# Verify basic fields are present
assert 'name = "test_zone"' in toml_str
assert 'description = "a test zone"' in toml_str
assert "width = 4" in toml_str
assert "height = 3" in toml_str
assert "toroidal = false" in toml_str
assert "spawn_x = 0" in toml_str
assert "spawn_y = 0" in toml_str
# Verify terrain section
assert "[terrain]" in toml_str
assert '"####"' in toml_str
assert '"#..#"' in toml_str
# Verify impassable tiles
assert "[terrain.impassable]" in toml_str
assert '"#"' in toml_str
def test_export_zone_round_trip():
"""Export a zone, load it back, verify it matches the original."""
original = Zone(
name="round_trip",
width=5,
height=4,
toroidal=True,
terrain=[
[".", ".", ".", ".", "."],
[".", "#", "#", "#", "."],
[".", "#", ".", "#", "."],
[".", ".", ".", ".", "."],
],
impassable={"#"},
spawn_x=2,
spawn_y=1,
)
original.description = "round trip test"
toml_str = export_zone(original)
# Write to temp file and load back
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
f.write(toml_str)
temp_path = pathlib.Path(f.name)
try:
loaded = load_zone(temp_path)
# Verify all fields match
assert loaded.name == original.name
assert loaded.description == original.description
assert loaded.width == original.width
assert loaded.height == original.height
assert loaded.toroidal == original.toroidal
assert loaded.spawn_x == original.spawn_x
assert loaded.spawn_y == original.spawn_y
assert loaded.terrain == original.terrain
assert loaded.impassable == original.impassable
finally:
temp_path.unlink()
def test_export_zone_with_portals():
"""Zone with Portal objects exports [[portals]] sections."""
zone = Zone(
name="portal_zone",
width=10,
height=10,
terrain=[["." for _ in range(10)] for _ in range(10)],
impassable=set(),
)
zone.description = "a zone with portals"
# Add portals
Portal(
name="tavern door",
location=zone,
x=5,
y=3,
target_zone="tavern",
target_x=1,
target_y=1,
)
Portal(
name="forest path",
aliases=["path", "entrance"],
location=zone,
x=2,
y=7,
target_zone="forest",
target_x=10,
target_y=5,
)
toml_str = export_zone(zone)
# Verify portals section exists
assert "[[portals]]" in toml_str
# Verify first portal
assert "x = 5" in toml_str
assert "y = 3" in toml_str
assert 'target = "tavern:1,1"' in toml_str
assert 'label = "tavern door"' in toml_str
# Verify second portal
assert "x = 2" in toml_str
assert "y = 7" in toml_str
assert 'target = "forest:10,5"' in toml_str
assert 'label = "forest path"' in toml_str
assert 'aliases = ["path", "entrance"]' in toml_str
def test_export_zone_with_portals_round_trip():
"""Export a zone with portals, load it back, verify portals match."""
zone = Zone(
name="portal_round_trip",
width=8,
height=6,
toroidal=False,
terrain=[["." for _ in range(8)] for _ in range(6)],
impassable=set(),
spawn_x=0,
spawn_y=0,
)
zone.description = "portal round trip test"
# Add portals
Portal(
name="tavern door",
location=zone,
x=5,
y=3,
target_zone="tavern",
target_x=1,
target_y=2,
)
Portal(
name="forest path",
aliases=["path"],
location=zone,
x=2,
y=4,
target_zone="forest",
target_x=10,
target_y=5,
)
toml_str = export_zone(zone)
# Write to temp file and load back
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
f.write(toml_str)
temp_path = pathlib.Path(f.name)
try:
loaded = load_zone(temp_path)
# Verify basic zone fields
assert loaded.name == zone.name
assert loaded.description == zone.description
assert loaded.width == zone.width
assert loaded.height == zone.height
# Verify portals were loaded correctly
portals = [obj for obj in loaded._contents if isinstance(obj, Portal)]
assert len(portals) == 2
# Sort by y coordinate for consistent ordering
portals.sort(key=lambda p: (p.y, p.x))
# Verify first portal (tavern door at 5,3)
assert portals[0].name == "tavern door"
assert portals[0].x == 5
assert portals[0].y == 3
assert portals[0].target_zone == "tavern"
assert portals[0].target_x == 1
assert portals[0].target_y == 2
# Verify second portal (forest path at 2,4)
assert portals[1].name == "forest path"
assert portals[1].x == 2
assert portals[1].y == 4
assert portals[1].target_zone == "forest"
assert portals[1].target_x == 10
assert portals[1].target_y == 5
assert "path" in portals[1].aliases
finally:
temp_path.unlink()
def test_export_zone_with_spawn_point():
"""spawn_x/spawn_y are in the output."""
zone = Zone(
name="spawn_zone",
width=10,
height=10,
terrain=[["." for _ in range(10)] for _ in range(10)],
spawn_x=5,
spawn_y=7,
)
zone.description = "a zone with spawn point"
toml_str = export_zone(zone)
assert "spawn_x = 5" in toml_str
assert "spawn_y = 7" in toml_str
def test_export_zone_to_file():
"""Write TOML to a file, load it back."""
zone = Zone(
name="file_zone",
width=3,
height=3,
terrain=[
["#", "#", "#"],
["#", ".", "#"],
["#", "#", "#"],
],
impassable={"#"},
)
zone.description = "exported to file"
with tempfile.TemporaryDirectory() as tmpdir:
output_path = pathlib.Path(tmpdir) / "test_zone.toml"
export_zone_to_file(zone, output_path)
# Verify file exists
assert output_path.exists()
# Load it back
loaded = load_zone(output_path)
assert loaded.name == zone.name
assert loaded.width == zone.width
assert loaded.height == zone.height
assert loaded.terrain == zone.terrain
def test_export_zone_with_ambient_messages():
"""Zone with ambient messages exports [ambient] section."""
zone = Zone(
name="ambient_zone",
width=5,
height=5,
terrain=[["." for _ in range(5)] for _ in range(5)],
ambient_messages=[
"Birds chirp overhead.",
"A cool breeze passes by.",
"Leaves rustle in the distance.",
],
ambient_interval=90,
)
zone.description = "a zone with ambient messages"
toml_str = export_zone(zone)
# Verify ambient section
assert "[ambient]" in toml_str
assert "interval = 90" in toml_str
assert "Birds chirp overhead." in toml_str
assert "A cool breeze passes by." in toml_str
assert "Leaves rustle in the distance." in toml_str
def test_export_zone_with_spawn_rules():
"""Zone with spawn rules exports [[spawns]] sections."""
zone = Zone(
name="spawn_zone",
width=10,
height=10,
terrain=[["." for _ in range(10)] for _ in range(10)],
spawn_rules=[
SpawnRule(mob="squirrel", max_count=2, respawn_seconds=180),
SpawnRule(mob="crow", max_count=1, respawn_seconds=300),
],
)
toml_str = export_zone(zone)
# Verify spawns sections
assert "[[spawns]]" in toml_str
assert 'mob = "squirrel"' in toml_str
assert "max_count = 2" in toml_str
assert "respawn_seconds = 180" in toml_str
assert 'mob = "crow"' in toml_str
assert "max_count = 1" in toml_str
assert "respawn_seconds = 300" in toml_str