diff --git a/evennia/commands/default/tests.py b/evennia/commands/default/tests.py index 65fb0fa639..f437779662 100644 --- a/evennia/commands/default/tests.py +++ b/evennia/commands/default/tests.py @@ -38,7 +38,6 @@ _RE = re.compile(r"^\+|-+\+|\+-+|--*|\|(?:\s|$)", re.MULTILINE) # ------------------------------------------------------------ -@mock.patch("evennia.utils.utils.delay") class CommandTest(EvenniaTest): """ Tests a command diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index 0e465e377b..ef8f9d24a5 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -264,14 +264,20 @@ class TestCmdSetMergers(TestCase): # test cmdhandler functions +import sys from evennia.commands import cmdhandler from twisted.trial.unittest import TestCase as TwistedTestCase +def _mockdelay(time, func, *args, **kwargs): + return func(*args, **kwargs) + + class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest): "Test the cmdhandler.get_and_merge_cmdsets function." def setUp(self): + self.patch(sys.modules['evennia.server.sessionhandler'], 'delay', _mockdelay) super(TestGetAndMergeCmdSets, self).setUp() self.cmdset_a = _CmdSetA() self.cmdset_b = _CmdSetB() @@ -325,6 +331,7 @@ class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest): a.no_exits = True a.no_channels = True self.set_cmdsets(self.obj1, a, b, c, d) + deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object", "") def _callback(cmdset): diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 23e4662ec3..ff6b01d5cf 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -815,9 +815,30 @@ class TestTutorialWorldMob(EvenniaTest): from evennia.contrib.tutorial_world import objects as tutobjects +from mock.mock import MagicMock +from twisted.trial.unittest import TestCase as TwistedTestCase + +from twisted.internet.base import DelayedCall +DelayedCall.debug = True -class TestTutorialWorldObjects(CommandTest): +def _mockdelay(tim, func, *args, **kwargs): + func(*args, **kwargs) + return MagicMock() + + +def _mockdeferLater(reactor, timedelay, callback, *args, **kwargs): + callback(*args, **kwargs) + return MagicMock() + + +class TestTutorialWorldObjects(TwistedTestCase, CommandTest): + + def setUp(self): + self.patch(sys.modules['evennia.contrib.tutorial_world.objects'], 'delay', _mockdelay) + self.patch(sys.modules['evennia.scripts.taskhandler'], 'deferLater', _mockdeferLater) + super(TestTutorialWorldObjects, self).setUp() + def test_tutorialobj(self): obj1 = create_object(tutobjects.TutorialObject, key="tutobj") obj1.reset() @@ -839,10 +860,7 @@ class TestTutorialWorldObjects(CommandTest): def test_lightsource(self): light = create_object(tutobjects.LightSource, key="torch", location=self.room1) - self.call(tutobjects.CmdLight(), "", "You light torch.", obj=light) - light._burnout() - if hasattr(light, "deferred"): - light.deferred.cancel() + self.call(tutobjects.CmdLight(), "", "A torch on the floor flickers and dies.|You light torch.", obj=light) self.assertFalse(light.pk) def test_crumblingwall(self): @@ -860,12 +878,12 @@ class TestTutorialWorldObjects(CommandTest): "You shift the weedy green root upwards.|Holding aside the root you think you notice something behind it ...", obj=wall) self.call(tutobjects.CmdPressButton(), "", "You move your fingers over the suspicious depression, then gives it a decisive push. First", obj=wall) - self.assertTrue(wall.db.button_exposed) - self.assertTrue(wall.db.exit_open) + # we patch out the delay, so these are closed immediately + self.assertFalse(wall.db.button_exposed) + self.assertFalse(wall.db.exit_open) wall.reset() - if hasattr(wall, "deferred"): - wall.deferred.cancel() wall.delete() + return wall.deferred def test_weapon(self): weapon = create_object(tutobjects.Weapon, key="sword", location=self.char1) diff --git a/evennia/contrib/tutorial_world/objects.py b/evennia/contrib/tutorial_world/objects.py index 3859de7d2d..b260770577 100644 --- a/evennia/contrib/tutorial_world/objects.py +++ b/evennia/contrib/tutorial_world/objects.py @@ -23,8 +23,7 @@ from future.utils import listvalues import random from evennia import DefaultObject, DefaultExit, Command, CmdSet -from evennia import utils -from evennia.utils import search +from evennia.utils import search, delay from evennia.utils.spawner import spawn # ------------------------------------------------------------- @@ -373,7 +372,7 @@ class LightSource(TutorialObject): # start the burn timer. When it runs out, self._burnout # will be called. We store the deferred so it can be # killed in unittesting. - self.deferred = utils.delay(60 * 3, self._burnout) + self.deferred = delay(60 * 3, self._burnout) return True @@ -645,7 +644,7 @@ class CrumblingWall(TutorialObject, DefaultExit): self.db.exit_open = True # start a 45 second timer before closing again. We store the deferred so it can be # killed in unittesting. - self.deferred = utils.delay(45, self.reset) + self.deferred = delay(45, self.reset) def _translate_position(self, root, ipos): """Translates the position into words""" diff --git a/evennia/scripts/taskhandler.py b/evennia/scripts/taskhandler.py index f4819ba076..a61dd6fb4a 100644 --- a/evennia/scripts/taskhandler.py +++ b/evennia/scripts/taskhandler.py @@ -4,7 +4,8 @@ Module containing the task handler for Evennia deferred tasks, persistent or not from datetime import datetime, timedelta -from twisted.internet import reactor, task +from twisted.internet import reactor +from twisted.internet.task import deferLater from evennia.server.models import ServerConfig from evennia.utils.logger import log_err from evennia.utils.dbserialize import dbserialize, dbunserialize @@ -143,7 +144,7 @@ class TaskHandler(object): args = [task_id] kwargs = {} - return task.deferLater(reactor, timedelay, callback, *args, **kwargs) + return deferLater(reactor, timedelay, callback, *args, **kwargs) def remove(self, task_id): """Remove a persistent task without executing it. @@ -189,7 +190,7 @@ class TaskHandler(object): now = datetime.now() for task_id, (date, callbac, args, kwargs) in self.tasks.items(): seconds = max(0, (date - now).total_seconds()) - task.deferLater(reactor, seconds, self.do_task, task_id) + deferLater(reactor, seconds, self.do_task, task_id) # Create the soft singleton diff --git a/evennia/server/sessionhandler.py b/evennia/server/sessionhandler.py index 5fb15930c9..39637bb00b 100644 --- a/evennia/server/sessionhandler.py +++ b/evennia/server/sessionhandler.py @@ -21,7 +21,7 @@ from evennia.commands.cmdhandler import CMD_LOGINSTART from evennia.utils.logger import log_trace from evennia.utils.utils import (variable_from_module, is_iter, to_str, to_unicode, - make_iter, + make_iter, delay, callables_from_module) from evennia.utils.inlinefuncs import parse_inlinefunc @@ -314,7 +314,6 @@ class ServerSessionHandler(SessionHandler): # this delay is necessary notably for Mudlet, which will fail on the connection screen # unless the MXP protocol has been negotiated. Unfortunately this may be too short for some # networks, the symptom is that < and > are not parsed by mudlet on first connection. - from evennia.utils.utils import delay delay(0.3, self.data_in, sess, text=[[CMD_LOGINSTART], {}]) # self.data_in(sess, text=[[CMD_LOGINSTART], {}]) diff --git a/evennia/utils/utils.py b/evennia/utils/utils.py index 1a159991ba..550b11eac3 100644 --- a/evennia/utils/utils.py +++ b/evennia/utils/utils.py @@ -948,7 +948,7 @@ def delay(timedelay, callback, *args, **kwargs): specified here. Note: - The task handler (`evennia.scripts.taskhandler.TASK_HANDLEr`) will + The task handler (`evennia.scripts.taskhandler.TASK_HANDLER`) will be called for persistent or non-persistent tasks. If persistent is set to True, the callback, its arguments and other keyword arguments will be saved in the database,