"""Tests for YAML map import script.""" from __future__ import annotations from pathlib import Path import pytest from mudlib.portal import Portal from mudlib.zones import load_zone def test_minimal_yaml_import(tmp_path: Path) -> None: """Test importing a minimal YAML map.""" yaml_content = """ name: test_zone width: 5 height: 5 terrain: rows: - "....." - "....." - "....." - "....." - "....." """ yaml_file = tmp_path / "test_zone.yaml" yaml_file.write_text(yaml_content) # Import the script module from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) # Verify TOML was created assert output_file.exists() assert output_file.name == "test_zone.toml" # Verify it can be loaded by existing zone loader zone = load_zone(output_file) assert zone.name == "test_zone" assert zone.width == 5 assert zone.height == 5 assert zone.description == "" assert zone.toroidal is True # default assert zone.spawn_x == 0 # default assert zone.spawn_y == 0 # default assert zone.safe is False # default assert len(zone.terrain) == 5 assert all(len(row) == 5 for row in zone.terrain) def test_full_featured_yaml_import(tmp_path: Path) -> None: """Test importing a YAML map with all features.""" yaml_content = """ name: complex_zone description: a complex test zone width: 10 height: 10 toroidal: false spawn: [5, 5] safe: true terrain: rows: - "##########" - "#........#" - "#........#" - "#........#" - "#........#" - "#........#" - "#........#" - "#........#" - "#........#" - "##########" impassable: ["#"] ambient: interval: 60 messages: - "wind howls..." - "a distant sound" portals: - x: 5 y: 0 target: "other_zone:10,10" label: "a wide path" aliases: ["path", "wide"] spawns: - mob: goblin max_count: 3 respawn_seconds: 300 home_region: x: [1, 9] y: [1, 9] """ yaml_file = tmp_path / "complex_zone.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) # Load and verify all fields zone = load_zone(output_file) assert zone.name == "complex_zone" assert zone.description == "a complex test zone" assert zone.width == 10 assert zone.height == 10 assert zone.toroidal is False assert zone.spawn_x == 5 assert zone.spawn_y == 5 assert zone.safe is True # Verify terrain assert len(zone.terrain) == 10 assert zone.terrain[0] == list("##########") assert zone.terrain[1] == list("#........#") # Verify impassable assert "#" in zone.impassable # Verify ambient messages assert zone.ambient_messages == ["wind howls...", "a distant sound"] assert zone.ambient_interval == 60 # Verify portals portals = [obj for obj in zone._contents if isinstance(obj, Portal)] assert len(portals) == 1 portal = portals[0] assert portal.x == 5 assert portal.y == 0 assert portal.target_zone == "other_zone" assert portal.target_x == 10 assert portal.target_y == 10 assert portal.name == "a wide path" assert portal.aliases == ["path", "wide"] # Verify spawn rules assert len(zone.spawn_rules) == 1 spawn = zone.spawn_rules[0] assert spawn.mob == "goblin" assert spawn.max_count == 3 assert spawn.respawn_seconds == 300 assert spawn.home_region == {"x": [1, 9], "y": [1, 9]} def test_missing_required_field_raises_error(tmp_path: Path) -> None: """Test that missing required fields raise appropriate errors.""" yaml_content = """ width: 5 height: 5 """ yaml_file = tmp_path / "incomplete.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map with pytest.raises(KeyError, match="name"): import_map(yaml_file, tmp_path) def test_spawn_list_format(tmp_path: Path) -> None: """Test that spawn coordinates as [x, y] list are parsed correctly.""" yaml_content = """ name: spawn_test width: 3 height: 3 spawn: [1, 2] terrain: rows: - "..." - "..." - "..." """ yaml_file = tmp_path / "spawn_test.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) zone = load_zone(output_file) assert zone.spawn_x == 1 assert zone.spawn_y == 2 def test_defaults_applied(tmp_path: Path) -> None: """Test that sensible defaults are applied for optional fields.""" yaml_content = """ name: defaults_test width: 3 height: 3 terrain: rows: - "..." - "..." - "..." """ yaml_file = tmp_path / "defaults_test.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) zone = load_zone(output_file) # Verify defaults assert zone.toroidal is True assert zone.spawn_x == 0 assert zone.spawn_y == 0 assert zone.safe is False assert zone.ambient_messages == [] assert zone.spawn_rules == [] def test_multiple_portals(tmp_path: Path) -> None: """Test importing multiple portals.""" yaml_content = """ name: multi_portal width: 5 height: 5 terrain: rows: - "....." - "....." - "....." - "....." - "....." portals: - x: 0 y: 0 target: "zone1:5,5" label: "north path" - x: 4 y: 4 target: "zone2:0,0" label: "south path" """ yaml_file = tmp_path / "multi_portal.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) zone = load_zone(output_file) portals = [obj for obj in zone._contents if isinstance(obj, Portal)] assert len(portals) == 2 def test_multiple_spawns(tmp_path: Path) -> None: """Test importing multiple spawn rules.""" yaml_content = """ name: multi_spawn width: 5 height: 5 terrain: rows: - "....." - "....." - "....." - "....." - "....." spawns: - mob: goblin max_count: 2 - mob: orc max_count: 1 respawn_seconds: 600 """ yaml_file = tmp_path / "multi_spawn.yaml" yaml_file.write_text(yaml_content) from scripts.import_map import import_map output_file = import_map(yaml_file, tmp_path) zone = load_zone(output_file) assert len(zone.spawn_rules) == 2 assert zone.spawn_rules[0].mob == "goblin" assert zone.spawn_rules[0].max_count == 2 assert zone.spawn_rules[1].mob == "orc" assert zone.spawn_rules[1].respawn_seconds == 600