""" Tests for the map/graph system. """ import unittest import sys import os import tempfile import json sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from src.map.graph import GameMap, Room, Edge, Task, Vent 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) class TestEdge(unittest.TestCase): """Tests for Edge dataclass.""" def test_edge_creation(self): edge = Edge(id="e1", room_a="a", room_b="b", distance=5.0) self.assertEqual(edge.id, "e1") self.assertEqual(edge.distance, 5.0) def test_edge_other_room(self): edge = Edge(id="e1", room_a="a", room_b="b", distance=5.0) 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")) self.game_map.add_room(Room(id="b", name="Room B")) self.game_map.add_room(Room(id="c", name="Room C")) self.game_map.add_room(Room(id="d", name="Room D")) self.game_map.add_edge(Edge(id="ab", room_a="a", room_b="b", distance=3.0)) self.game_map.add_edge(Edge(id="bc", room_a="b", room_b="c", distance=4.0)) self.game_map.add_edge(Edge(id="bd", room_a="b", room_b="d", distance=2.0)) 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.assertEqual(edge.distance, 3.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) def test_path_distance(self): path = self.game_map.find_path("a", "c") distance = self.game_map.path_distance(path) self.assertEqual(distance, 7.0) # 3 + 4 def test_shortest_path(self): # Add direct edge from a to d (should be longer) self.game_map.add_edge(Edge(id="ad", room_a="a", room_b="d", distance=10.0)) # Shortest path should still go through b path = self.game_map.find_path("a", "d") distance = self.game_map.path_distance(path) self.assertEqual(distance, 5.0) # 3 + 2 via b 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")) game_map.add_room(Room(id="b", name="B")) game_map.add_edge(Edge(id="ab", room_a="a", room_b="b", distance=5.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) vent = Vent(id="v1", connects_to=["v2"]) game_map.add_room(Room(id="a", name="A", tasks=[task], vent=vent)) game_map.add_room(Room(id="b", name="B")) game_map.add_edge(Edge(id="ab", room_a="a", room_b="b", distance=5.0)) 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) if __name__ == "__main__": unittest.main()