"""Tests for zone loading from TOML files.""" import pathlib import tempfile from mudlib.zones import load_zone, load_zones def test_load_zone(): """Load a zone from TOML file.""" # Create a temporary TOML file with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "test_zone" description = "a test zone" width = 4 height = 3 toroidal = false [terrain] rows = [ "####", "#..#", "####", ] [terrain.impassable] tiles = ["#"] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert zone.name == "test_zone" assert zone.width == 4 assert zone.height == 3 assert zone.toroidal is False assert len(zone.terrain) == 3 assert zone.terrain[0] == ["#", "#", "#", "#"] assert zone.terrain[1] == ["#", ".", ".", "#"] assert zone.terrain[2] == ["#", "#", "#", "#"] assert zone.impassable == {"#"} finally: temp_path.unlink() def test_load_zone_toroidal(): """Load a toroidal zone.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "toroidal_zone" description = "a toroidal test zone" width = 3 height = 2 toroidal = true [terrain] rows = [ "...", "...", ] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert zone.toroidal is True # Default impassable set from Zone class assert zone.impassable == {"^", "~"} finally: temp_path.unlink() def test_load_zones_from_directory(): """Load all zones from a directory.""" with tempfile.TemporaryDirectory() as tmpdir: tmpdir_path = pathlib.Path(tmpdir) # Create two zone files zone1_path = tmpdir_path / "zone1.toml" zone1_path.write_text(""" name = "zone1" description = "first zone" width = 2 height = 2 toroidal = false [terrain] rows = [ "..", "..", ] """) zone2_path = tmpdir_path / "zone2.toml" zone2_path.write_text(""" name = "zone2" description = "second zone" width = 3 height = 3 toroidal = true [terrain] rows = [ "###", "#.#", "###", ] """) # Create a non-TOML file that should be ignored (tmpdir_path / "readme.txt").write_text("not a zone file") zones = load_zones(tmpdir_path) assert len(zones) == 2 assert "zone1" in zones assert "zone2" in zones assert zones["zone1"].name == "zone1" assert zones["zone2"].name == "zone2" def test_load_tavern_zone(): """Load the actual tavern zone file.""" # This tests the real tavern.toml file in content/zones/ project_root = pathlib.Path(__file__).resolve().parents[1] tavern_path = project_root / "content" / "zones" / "tavern.toml" zone = load_zone(tavern_path) assert zone.name == "tavern" assert zone.width == 8 assert zone.height == 6 assert zone.toroidal is False assert zone.spawn_x == 1 assert zone.spawn_y == 1 assert len(zone.terrain) == 6 assert zone.terrain[0] == ["#", "#", "#", "#", "#", "#", "#", "#"] assert zone.terrain[5] == ["#", "#", "#", "#", ".", "#", "#", "#"] assert zone.impassable == {"#"} # Check that interior is passable assert zone.is_passable(1, 1) assert zone.is_passable(4, 3) # Check that walls are impassable assert not zone.is_passable(0, 0) assert not zone.is_passable(7, 0) def test_load_zone_with_spawn_point(): """Load a zone with spawn_x and spawn_y defined.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "spawn_zone" description = "a zone with spawn point" width = 10 height = 10 spawn_x = 5 spawn_y = 7 [terrain] rows = [ "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", ] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert zone.spawn_x == 5 assert zone.spawn_y == 7 finally: temp_path.unlink() def test_load_zone_default_spawn_point(): """Load a zone without spawn point defined defaults to (0, 0).""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "default_spawn" description = "a zone without spawn point" width = 5 height = 5 [terrain] rows = [ ".....", ".....", ".....", ".....", ".....", ] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert zone.spawn_x == 0 assert zone.spawn_y == 0 finally: temp_path.unlink() def test_load_zone_with_portals(): """Load a zone with portals defined.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "portal_zone" description = "a zone with portals" width = 10 height = 10 [terrain] rows = [ "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", "..........", ] [[portals]] x = 5 y = 3 target = "tavern:1,1" label = "tavern door" [[portals]] x = 2 y = 7 target = "forest:10,5" label = "forest path" """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) # Find portals in zone contents portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"] assert len(portals) == 2 # Check first portal (tavern door at 5,3) tavern_portal = [p for p in portals if p.name == "tavern door"][0] assert tavern_portal.x == 5 assert tavern_portal.y == 3 assert tavern_portal.target_zone == "tavern" assert tavern_portal.target_x == 1 assert tavern_portal.target_y == 1 assert tavern_portal.location == zone # Check second portal (forest path at 2,7) forest_portal = [p for p in portals if p.name == "forest path"][0] assert forest_portal.x == 2 assert forest_portal.y == 7 assert forest_portal.target_zone == "forest" assert forest_portal.target_x == 10 assert forest_portal.target_y == 5 assert forest_portal.location == zone # Verify portals are at correct coordinates contents_at_5_3 = zone.contents_at(5, 3) assert tavern_portal in contents_at_5_3 contents_at_2_7 = zone.contents_at(2, 7) assert forest_portal in contents_at_2_7 finally: temp_path.unlink() def test_load_zone_without_portals(): """Load a zone without portals section works fine.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "no_portals" description = "a zone without portals" width = 3 height = 3 [terrain] rows = [ "...", "...", "...", ] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) # Should have no portals portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"] assert len(portals) == 0 finally: temp_path.unlink() def test_load_zone_portal_with_aliases(): """Portal can have optional aliases field in TOML.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write(""" name = "alias_zone" description = "a zone with aliased portal" width = 5 height = 5 [terrain] rows = [ ".....", ".....", ".....", ".....", ".....", ] [[portals]] x = 2 y = 2 target = "elsewhere:0,0" label = "mysterious gateway" aliases = ["gateway", "gate", "portal"] """) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) portals = [obj for obj in zone._contents if obj.__class__.__name__ == "Portal"] assert len(portals) == 1 portal = portals[0] assert portal.name == "mysterious gateway" assert portal.aliases == ["gateway", "gate", "portal"] finally: temp_path.unlink()