""" 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()