From aa9beb43edbaa0b9b99e7dbb8e28beaf9f704ded Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 10 Jul 2021 12:59:23 +0200 Subject: [PATCH] Fix mapping unittests --- evennia/commands/default/building.py | 22 ++++++--- evennia/contrib/xyzgrid/commands.py | 67 +++++++++++++++------------- evennia/contrib/xyzgrid/tests.py | 21 +++++---- evennia/contrib/xyzgrid/xyzgrid.py | 18 ++++---- evennia/objects/objects.py | 16 +++---- 5 files changed, 80 insertions(+), 64 deletions(-) diff --git a/evennia/commands/default/building.py b/evennia/commands/default/building.py index dff960ee43..817b38d4f0 100644 --- a/evennia/commands/default/building.py +++ b/evennia/commands/default/building.py @@ -2982,13 +2982,14 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS): super().parse() self.obj_to_teleport = self.caller self.destination = None - if self.lhs: + if self.rhs: self.obj_to_teleport = self.caller.search(self.lhs, global_search=True) if not self.obj_to_teleport: self.caller.msg("Did not find object to teleport.") raise InterruptCommand - if self.rhs: self.destination = self.caller.search(self.rhs, global_search=True) + elif self.lhs: + self.destination = self.caller.search(self.lhs, global_search=True) def func(self): """Performs the teleport""" @@ -2999,6 +3000,11 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS): if "tonone" in self.switches: # teleporting to None + + if destination: + # in this case lhs is always the object to teleport + obj_to_teleport = destination + if obj_to_teleport.has_account: caller.msg( "Cannot teleport a puppeted object " @@ -3041,14 +3047,20 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS): return # try the teleport - if obj_to_teleport.move_to( + if not obj_to_teleport.location: + # teleporting from none-location + obj_to_teleport.location = destination + caller.msg(f"Teleported {obj_to_teleport} None -> {destination}") + elif obj_to_teleport.move_to( destination, quiet="quiet" in self.switches, emit_to_obj=caller, use_destination="intoexit" not in self.switches): if obj_to_teleport == caller: - caller.msg("Teleported to %s." % destination) + caller.msg(f"Teleported to {destination}.") else: - caller.msg("Teleported %s -> %s." % (obj_to_teleport, destination)) + caller.msg(f"Teleported {obj_to_teleport} -> {destination}.") + else: + caller.msg("Teleportation failed.") class CmdScript(COMMAND_DEFAULT_CLASS): diff --git a/evennia/contrib/xyzgrid/commands.py b/evennia/contrib/xyzgrid/commands.py index a8d765de85..eb59067750 100644 --- a/evennia/contrib/xyzgrid/commands.py +++ b/evennia/contrib/xyzgrid/commands.py @@ -8,7 +8,7 @@ the commands with XYZ-aware equivalents. """ from evennia import InterruptCommand -from evennia import MuxCommand, CmdSet +from evennia import default_cmds, CmdSet from evennia.commands.default import building, general from evennia.contrib.xyzgrid.xyzroom import XYZRoom from evennia.utils.utils import inherits_from @@ -73,44 +73,51 @@ class CmdXYZTeleport(building.CmdTeleport): are given, the target is a location on the XYZGrid. """ + def _search_by_xyz(self, inp): + X, Y, *Z = inp.split(",", 2) + if Z: + # Z was specified + Z = Z[0] + else: + # use current location's Z, if it exists + try: + xyz = self.caller.xyz + except AttributeError: + self.caller.msg("Z-coordinate is also required since you are not currently " + "in a room with a Z coordinate of its own.") + raise InterruptCommand + else: + Z = xyz[2] + # search by coordinate + X, Y, Z = str(X).strip(), str(Y).strip(), str(Z).strip() + try: + self.destination = XYZRoom.objects.get_xyz(xyz=(X, Y, Z)) + except XYZRoom.DoesNotExist: + self.caller.msg("Found no target XYZRoom at ({X},{Y},{Y}).") + raise InterruptCommand def parse(self): - MuxCommand.parse(self) + default_cmds.MuxCommand.parse(self) self.obj_to_teleport = self.caller self.destination = None - rhs = self.rhs - if self.lhs: + + if self.rhs: self.obj_to_teleport = self.caller.search(self.lhs, global_search=True) if not self.obj_to_teleport: self.caller.msg("Did not find object to teleport.") raise InterruptCommand - if rhs: - if all(char in rhs for char in ("(", ")", ",")): + if all(char in self.rhs for char in ("(", ")", ",")): # search by (X,Y) or (X,Y,Z) - X, Y, *Z = rhs.split(",", 2) - if Z: - # Z was specified - Z = Z[0] - else: - # use current location's Z, if it exists - try: - xyz = self.caller.xyz - except AttributeError: - self.caller.msg("Z-coordinate is also required since you are not currently " - "in a room with a Z coordinate of its own.") - raise InterruptCommand - else: - Z = xyz[2] - # search by coordinate - X, Y, Z = str(X).strip(), str(Y).strip(), str(Z).strip() - try: - self.obj_to_teleport = XYZRoom.objects.get_xyz(xyz=(X, Y, Z)) - except XYZRoom.DoesNotExist: - self.caller.msg("Found no target XYZRoom at ({X},{Y},{Y}).") - raise InterruptCommand + self._search_by_xyz(self.rhs) else: - # regular search - self.destination = self.caller.search(rhs, global_search=True) + # fallback to regular search by name/alias + self.destination = self.caller.search(self.rhs, global_search=True) + + elif self.lhs: + if all(char in self.rhs for char in ("(", ")", ",")): + self._search_by_xyz(self.lhs) + else: + self.destination = self.caller.search(self.lhs, global_search=True) class CmdXYZOpen(building.CmdOpen): @@ -143,7 +150,7 @@ class CmdXYZOpen(building.CmdOpen): if not self.args or not self.rhs: self.caller.msg("Usage: open [;alias...][:typeclass]" "[,[;alias..][:typeclass]]] " - "= ") + "= ") raise InterruptCommand if not self.location: self.caller.msg("You cannot create an exit from a None-location.") diff --git a/evennia/contrib/xyzgrid/tests.py b/evennia/contrib/xyzgrid/tests.py index 71c9c33aea..c124788304 100644 --- a/evennia/contrib/xyzgrid/tests.py +++ b/evennia/contrib/xyzgrid/tests.py @@ -6,9 +6,9 @@ Tests for the XYZgrid system. from time import time from random import randint -from unittest import TestCase from parameterized import parameterized -from django.test import override_settings +from django.test import TestCase +from evennia.utils.test_resources import EvenniaTest from . import xymap, xyzgrid, map_legend, xyzroom @@ -341,7 +341,7 @@ MAP12b = r""" """ -class _MapTest(TestCase): +class _MapTest(EvenniaTest): """ Parent for map tests @@ -351,6 +351,7 @@ class _MapTest(TestCase): def setUp(self): """Set up grid and map""" + super().setUp() self.grid, err = xyzgrid.XYZGrid.create("testgrid") self.grid.add_maps(self.map_data) self.map = self.grid.get_map(self.map_data['zcoord']) @@ -1138,7 +1139,7 @@ class TestMapStressTest(TestCase): f"slower than expected {max_time}s.") -class TestXYZGrid(TestCase): +class TestXYZGrid(EvenniaTest): """ Test base grid class with a single map, including spawning objects. @@ -1187,12 +1188,13 @@ class Map12bTransition(map_legend.MapTransitionMapNode): target_map_xyz = (0, 1, "map12a") -class TestXYZGridTransition(TestCase): +class TestXYZGridTransition(EvenniaTest): """ Test the XYZGrid class and transitions between maps. """ def setUp(self): + super().setUp() self.grid, err = xyzgrid.XYZGrid.create("testgrid") self.map_data12a = { @@ -1243,18 +1245,19 @@ class TestXYZGridTransition(TestCase): self.assertEqual(east_exit.db_destination, room2) self.assertEqual(west_exit.db_destination, room1) -class TestBuildExampleGrid(TestCase): +class TestBuildExampleGrid(EvenniaTest): """ Test building the map_example (this takes about 30s) """ def setUp(self): # build and populate grid + super().setUp() self.grid, err = xyzgrid.XYZGrid.create("testgrid") - def _log(msg): - print(msg) - self.grid.log = _log + # def _log(msg): + # print(msg) + # self.grid.log = _log def tearDown(self): self.grid.delete() diff --git a/evennia/contrib/xyzgrid/xyzgrid.py b/evennia/contrib/xyzgrid/xyzgrid.py index a9f14a10ed..f27b6ee3ae 100644 --- a/evennia/contrib/xyzgrid/xyzgrid.py +++ b/evennia/contrib/xyzgrid/xyzgrid.py @@ -121,14 +121,7 @@ class XYZGrid(DefaultScript): # store self.log(f"Loaded and linked {nmaps} map(s).") - - def at_init(self): - """ - Called when the script loads into memory (on creation or after a reload). This will load all - map data into memory. - - """ - self.reload() + self.ndb.loaded = True def maps_from_module(self, module): """ @@ -254,8 +247,15 @@ def get_xyzgrid(): xyzgrid, err = XYZGrid.create("XYZGrid") if err: raise RuntimeError(err) + xyzgrid.reload() return xyzgrid elif len(xyzgrid) > 1: ("Warning: More than one XYZGrid instances were found. This is an error and " "only the first one will be used. Delete the other one(s) manually.") - return xyzgrid[0] + xyzgrid = xyzgrid[0] + try: + if not xyzgrid.ndb.loaded: + xyzgrid.reload() + except Exception as err: + xyzgrid.log(str(err)) + return xyzgrid diff --git a/evennia/objects/objects.py b/evennia/objects/objects.py index 1294e7e0ec..1026b7199a 100644 --- a/evennia/objects/objects.py +++ b/evennia/objects/objects.py @@ -816,7 +816,6 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): use_destination=True, to_none=False, move_hooks=True, - alternative_source=None, **kwargs, ): """ @@ -838,10 +837,6 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): move_hooks (bool): If False, turn off the calling of move-related hooks (at_before/after_move etc) with quiet=True, this is as quiet a move as can be done. - alternative_source (Object, optional): Normally, the current `self.location` is - assumed the 'source' of the move. This allows for replacing this - with a custom source (for example to create a teleporter room that - retains the original source when moving to another place). Keyword Args: Passed on to announce_move_to and announce_move_from hooks. @@ -876,8 +871,6 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): if not emit_to_obj: emit_to_obj = self - source_location = alternative_source or self.location - if not destination: if to_none: # immediately move to None. There can be no hooks called since @@ -889,16 +882,18 @@ class DefaultObject(ObjectDB, metaclass=TypeclassBase): if destination.destination and use_destination: # traverse exits destination = destination.destination - # Before the move, call eventual pre-commands. if move_hooks: try: - if not source_location.at_before_move(destination, **kwargs): + if not self.at_before_move(destination, **kwargs): return False except Exception as err: logerr(errtxt.format(err="at_before_move()"), err) return False + # Save the old location + source_location = self.location + # Call hook on source location if move_hooks and source_location: try: @@ -2464,7 +2459,6 @@ class DefaultRoom(DefaultObject): obj.db.desc = description if description else _("This is a room.") except Exception as e: - raise errors.append("An error occurred while creating this '%s' object." % key) logger.log_err(e) @@ -2671,7 +2665,7 @@ class DefaultExit(DefaultObject): obj.db.desc = description if description else _("This is an exit.") except Exception as e: - errors.append("An error occurred while creating this '%s' object (%s)." % key) + errors.append("An error occurred while creating this '%s' object." % key) logger.log_err(e) return obj, errors