"""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 obj.__class__.__name__ == "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