257 lines
9.2 KiB
Python
257 lines
9.2 KiB
Python
"""
|
|
Tests for the map/graph system.
|
|
"""
|
|
|
|
import unittest
|
|
import sys
|
|
import os
|
|
import tempfile
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from src.map.graph import GameMap, Room, Edge, Task, Vent
|
|
from src.engine.types import Position
|
|
|
|
|
|
class TestRoom(unittest.TestCase):
|
|
"""Tests for Room dataclass."""
|
|
|
|
def test_room_creation(self):
|
|
room = Room(id="test", name="Test Room")
|
|
self.assertEqual(room.id, "test")
|
|
self.assertEqual(room.name, "Test Room")
|
|
self.assertEqual(room.tasks, [])
|
|
self.assertIsNone(room.vent)
|
|
|
|
def test_room_with_tasks(self):
|
|
task = Task(id="task1", name="Do Thing", duration=5.0)
|
|
room = Room(id="test", name="Test Room", tasks=[task])
|
|
self.assertEqual(len(room.tasks), 1)
|
|
self.assertEqual(room.tasks[0].duration, 5.0)
|
|
|
|
def test_room_with_vent(self):
|
|
vent = Vent(id="vent1", connects_to=["vent2", "vent3"])
|
|
room = Room(id="test", name="Test Room", vent=vent)
|
|
self.assertIsNotNone(room.vent)
|
|
self.assertEqual(len(room.vent.connects_to), 2)
|
|
|
|
def test_room_with_center(self):
|
|
room = Room(id="test", name="Test Room", center=Position(x=100, y=200))
|
|
self.assertEqual(room.center.x, 100)
|
|
self.assertEqual(room.center.y, 200)
|
|
|
|
def test_room_contains_point(self):
|
|
room = Room(
|
|
id="test", name="Test Room",
|
|
center=Position(x=100, y=100),
|
|
bounds=(Position(x=0, y=0), Position(x=200, y=200))
|
|
)
|
|
self.assertTrue(room.contains_point(Position(x=100, y=100)))
|
|
self.assertTrue(room.contains_point(Position(x=50, y=50)))
|
|
self.assertFalse(room.contains_point(Position(x=300, y=100)))
|
|
|
|
|
|
class TestEdge(unittest.TestCase):
|
|
"""Tests for Edge dataclass."""
|
|
|
|
def test_edge_creation(self):
|
|
edge = Edge(id="e1", room_a="a", room_b="b")
|
|
self.assertEqual(edge.id, "e1")
|
|
self.assertEqual(edge.room_a, "a")
|
|
|
|
def test_edge_with_waypoints(self):
|
|
edge = Edge(
|
|
id="e1", room_a="a", room_b="b",
|
|
waypoints=[Position(x=0, y=0), Position(x=100, y=0)]
|
|
)
|
|
self.assertAlmostEqual(edge.distance, 100.0)
|
|
|
|
def test_edge_other_room(self):
|
|
edge = Edge(id="e1", room_a="a", room_b="b")
|
|
self.assertEqual(edge.other_room("a"), "b")
|
|
self.assertEqual(edge.other_room("b"), "a")
|
|
|
|
|
|
class TestGameMap(unittest.TestCase):
|
|
"""Tests for GameMap class."""
|
|
|
|
def setUp(self):
|
|
"""Create a simple test map."""
|
|
self.game_map = GameMap()
|
|
|
|
# Create rooms: A -- B -- C
|
|
# |
|
|
# D
|
|
self.game_map.add_room(Room(id="a", name="Room A", center=Position(x=0, y=0)))
|
|
self.game_map.add_room(Room(id="b", name="Room B", center=Position(x=100, y=0)))
|
|
self.game_map.add_room(Room(id="c", name="Room C", center=Position(x=200, y=0)))
|
|
self.game_map.add_room(Room(id="d", name="Room D", center=Position(x=100, y=100)))
|
|
|
|
# Create edges with waypoints
|
|
self.game_map.add_edge(Edge(
|
|
id="ab", room_a="a", room_b="b",
|
|
waypoints=[Position(x=0, y=0), Position(x=50, y=0), Position(x=100, y=0)]
|
|
))
|
|
self.game_map.add_edge(Edge(
|
|
id="bc", room_a="b", room_b="c",
|
|
waypoints=[Position(x=100, y=0), Position(x=200, y=0)]
|
|
))
|
|
self.game_map.add_edge(Edge(
|
|
id="bd", room_a="b", room_b="d",
|
|
waypoints=[Position(x=100, y=0), Position(x=100, y=100)]
|
|
))
|
|
|
|
def test_add_room(self):
|
|
self.assertEqual(len(self.game_map.rooms), 4)
|
|
self.assertIn("a", self.game_map.rooms)
|
|
|
|
def test_add_edge(self):
|
|
self.assertEqual(len(self.game_map.edges), 3)
|
|
self.assertIn("ab", self.game_map.edges)
|
|
|
|
def test_get_room(self):
|
|
room = self.game_map.get_room("a")
|
|
self.assertIsNotNone(room)
|
|
self.assertEqual(room.name, "Room A")
|
|
|
|
self.assertIsNone(self.game_map.get_room("nonexistent"))
|
|
|
|
def test_get_edge(self):
|
|
edge = self.game_map.get_edge("ab")
|
|
self.assertIsNotNone(edge)
|
|
self.assertAlmostEqual(edge.distance, 100.0)
|
|
|
|
def test_get_neighbors(self):
|
|
neighbors = self.game_map.get_neighbors("b")
|
|
self.assertEqual(len(neighbors), 3) # a, c, d
|
|
neighbor_rooms = [n[1] for n in neighbors]
|
|
self.assertIn("a", neighbor_rooms)
|
|
self.assertIn("c", neighbor_rooms)
|
|
self.assertIn("d", neighbor_rooms)
|
|
|
|
def test_find_edge(self):
|
|
edge = self.game_map.find_edge("a", "b")
|
|
self.assertIsNotNone(edge)
|
|
self.assertEqual(edge.id, "ab")
|
|
|
|
# Reverse direction
|
|
edge = self.game_map.find_edge("b", "a")
|
|
self.assertIsNotNone(edge)
|
|
|
|
# Non-adjacent
|
|
self.assertIsNone(self.game_map.find_edge("a", "c"))
|
|
|
|
def test_find_path_adjacent(self):
|
|
path = self.game_map.find_path("a", "b")
|
|
self.assertEqual(path, ["ab"])
|
|
|
|
def test_find_path_multi_hop(self):
|
|
path = self.game_map.find_path("a", "c")
|
|
self.assertEqual(path, ["ab", "bc"])
|
|
|
|
def test_find_path_same_room(self):
|
|
path = self.game_map.find_path("a", "a")
|
|
self.assertEqual(path, [])
|
|
|
|
def test_find_path_no_path(self):
|
|
# Add isolated room
|
|
self.game_map.add_room(Room(id="isolated", name="Isolated"))
|
|
path = self.game_map.find_path("a", "isolated")
|
|
self.assertIsNone(path)
|
|
|
|
|
|
class TestMapSerialization(unittest.TestCase):
|
|
"""Tests for map serialization."""
|
|
|
|
def test_to_dict(self):
|
|
game_map = GameMap()
|
|
game_map.add_room(Room(id="a", name="A", center=Position(x=0, y=0)))
|
|
game_map.add_room(Room(id="b", name="B", center=Position(x=100, y=0)))
|
|
game_map.add_edge(Edge(
|
|
id="ab", room_a="a", room_b="b",
|
|
waypoints=[Position(x=0, y=0), Position(x=100, y=0)]
|
|
))
|
|
|
|
data = game_map.to_dict()
|
|
self.assertEqual(len(data["rooms"]), 2)
|
|
self.assertEqual(len(data["edges"]), 1)
|
|
|
|
def test_save_and_load(self):
|
|
game_map = GameMap()
|
|
task = Task(id="t1", name="Task", duration=3.0, position=Position(x=50, y=50))
|
|
vent = Vent(id="v1", connects_to=["v2"], position=Position(x=60, y=60))
|
|
game_map.add_room(Room(
|
|
id="a", name="A",
|
|
center=Position(x=50, y=50),
|
|
bounds=(Position(x=0, y=0), Position(x=100, y=100)),
|
|
tasks=[task], vent=vent
|
|
))
|
|
game_map.add_room(Room(id="b", name="B", center=Position(x=200, y=50)))
|
|
game_map.add_edge(Edge(
|
|
id="ab", room_a="a", room_b="b",
|
|
waypoints=[Position(x=100, y=50), Position(x=200, y=50)]
|
|
))
|
|
|
|
with tempfile.NamedTemporaryFile(suffix=".json", delete=False) as f:
|
|
game_map.save(f.name)
|
|
|
|
loaded = GameMap.load(f.name)
|
|
self.assertEqual(len(loaded.rooms), 2)
|
|
self.assertEqual(len(loaded.edges), 1)
|
|
self.assertEqual(loaded.rooms["a"].tasks[0].duration, 3.0)
|
|
self.assertIsNotNone(loaded.rooms["a"].vent)
|
|
|
|
os.unlink(f.name)
|
|
|
|
|
|
class TestSkeldMap(unittest.TestCase):
|
|
"""Tests for the actual Skeld map."""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
map_path = os.path.join(
|
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
|
"data", "maps", "skeld.json"
|
|
)
|
|
cls.skeld = GameMap.load(map_path)
|
|
|
|
def test_skeld_has_all_rooms(self):
|
|
expected_rooms = [
|
|
"cafeteria", "weapons", "navigation", "o2", "admin",
|
|
"storage", "communications", "shields", "electrical",
|
|
"lower_engine", "security", "reactor", "upper_engine", "medbay"
|
|
]
|
|
for room_id in expected_rooms:
|
|
self.assertIn(room_id, self.skeld.rooms, f"Missing room: {room_id}")
|
|
|
|
def test_skeld_connectivity(self):
|
|
# Every room should be reachable from cafeteria
|
|
for room_id in self.skeld.rooms:
|
|
path = self.skeld.find_path("cafeteria", room_id)
|
|
self.assertIsNotNone(path, f"No path to {room_id}")
|
|
|
|
def test_skeld_has_vents(self):
|
|
vent_rooms = ["weapons", "navigation", "admin", "electrical",
|
|
"lower_engine", "security", "reactor", "upper_engine", "medbay", "shields"]
|
|
for room_id in vent_rooms:
|
|
room = self.skeld.get_room(room_id)
|
|
self.assertIsNotNone(room.vent, f"{room_id} should have a vent")
|
|
|
|
def test_vent_connectivity(self):
|
|
# Check medbay-security-electrical vent network
|
|
medbay = self.skeld.get_room("medbay")
|
|
self.assertIn("vent_security", medbay.vent.connects_to)
|
|
self.assertIn("vent_elec", medbay.vent.connects_to)
|
|
|
|
def test_skeld_has_walls(self):
|
|
"""Skeld should have wall geometry for raycasting."""
|
|
self.assertGreater(len(self.skeld.walls), 0)
|
|
|
|
def test_skeld_has_spawn_points(self):
|
|
"""Skeld should have spawn points."""
|
|
self.assertIn("cafeteria", self.skeld.spawn_points)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|