diff --git a/evennia/commands/cmdhandler.py b/evennia/commands/cmdhandler.py index fbe2a5772..baa58f08c 100644 --- a/evennia/commands/cmdhandler.py +++ b/evennia/commands/cmdhandler.py @@ -290,7 +290,7 @@ def get_and_merge_cmdsets(caller, session, player, obj, callertype): # we are calling the command from the player level report_to = player player_cmdset = yield _get_cmdsets(player) - channel_cmdset = yield _get_channel_cmdset(player, player_cmdset) + channel_cmdset = yield _get_channel_cmdset(player) cmdsets = player_cmdset + channel_cmdset if obj: obj_cmdset = yield _get_cmdsets(obj) diff --git a/evennia/commands/cmdset.py b/evennia/commands/cmdset.py index 02f26d23e..04815c639 100644 --- a/evennia/commands/cmdset.py +++ b/evennia/commands/cmdset.py @@ -403,9 +403,10 @@ class CmdSet(with_metaclass(_CmdSetMeta, object)): cmdset_c.no_objs = cmdset_a.no_objs cmdset_c.duplicates = cmdset_a.duplicates - if self.key.startswith("_"): + if cmdset_a.key.startswith("_"): # don't rename new output if the merge set's name starts with _ - cmdset_c.key = cmdset_a.key + # these are usually things like exitcmdsets and channelcmdsets) + cmdset_c.key = self.key else: # B higher priority than A diff --git a/evennia/commands/tests.py b/evennia/commands/tests.py index 95e670cb5..2b9da9913 100644 --- a/evennia/commands/tests.py +++ b/evennia/commands/tests.py @@ -3,7 +3,7 @@ Unit testing for the Command system itself. """ -from evennia.utils.test_resources import EvenniaTest, SESSIONS +from evennia.utils.test_resources import EvenniaTest, SESSIONS, TestCase from evennia.commands.cmdset import CmdSet from evennia.commands.command import Command @@ -59,7 +59,7 @@ class _CmdSetD(CmdSet): # testing Command Sets -class TestCmdSetMergers(EvenniaTest): +class TestCmdSetMergers(TestCase): "Test merging of cmdsets" def setUp(self): super(TestCmdSetMergers, self).setUp() @@ -68,6 +68,73 @@ class TestCmdSetMergers(EvenniaTest): self.cmdset_c = _CmdSetC() self.cmdset_d = _CmdSetD() + def test_union(self): + a, c = self.cmdset_a, self.cmdset_c + cmdset_f = a + c # same-prio + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2) + cmdset_f = c + a # same-prio, inverse order + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + a.priority = 1 + cmdset_f = a + c # high prio A + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + + def test_intersect(self): + a, c = self.cmdset_a, self.cmdset_c + a.mergetype = "Intersect" + cmdset_f = a + c # same-prio - c's Union kicks in + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2) + cmdset_f = c + a # same-prio - a's Intersect kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + a.priority = 1 + cmdset_f = a + c # high prio A, intersect kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + + def test_replace(self): + a, c = self.cmdset_a, self.cmdset_c + c.mergetype = "Replace" + cmdset_f = a + c # same-prio. C's Replace kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2) + cmdset_f = c + a # same-prio. A's Union kicks in + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + c.priority = 1 + cmdset_f = c + a # c higher prio. C's Replace kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 0) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 2) + + def test_remove(self): + a, c = self.cmdset_a, self.cmdset_c + c.mergetype = "Remove" + cmdset_f = a + c # same-prio. C's Remove kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + cmdset_f = c + a # same-prio. A's Union kicks in + self.assertEqual(len(cmdset_f.commands), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 4) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + c.priority = 1 + cmdset_f = c + a # c higher prio. C's Remove kicks in + self.assertEqual(len(cmdset_f.commands), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "A"), 2) + self.assertEqual(sum(1 for cmd in cmdset_f.commands if cmd.from_cmdset == "C"), 0) + def test_order(self): "Merge in reverse- and forward orders, same priorities" a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d @@ -159,6 +226,61 @@ class TestCmdSetMergers(EvenniaTest): cmdset_f = d + b + c + a # two last mergers duplicates=True self.assertEqual(len(cmdset_f.commands), 10) +# test cmdhandler functions + +from evennia.commands import cmdhandler +from twisted.trial.unittest import TestCase as TwistedTestCase +class TestGetAndMergeCmdSets(TwistedTestCase, EvenniaTest): + "Test the cmdhandler.get_and_merge_cmdsets function." + def setUp(self): + super(TestGetAndMergeCmdSets, self).setUp() + self.cmdset_a = _CmdSetA() + self.cmdset_b = _CmdSetB() + self.cmdset_c = _CmdSetC() + self.cmdset_d = _CmdSetD() + + def set_cmdsets(self, obj, *args): + "Set cmdets on obj in the order given in *args" + for cmdset in args: + obj.cmdset.add(cmdset) + + def test_from_session(self): + self.set_cmdsets(self.session, self.cmdset_a) + deferred = cmdhandler.get_and_merge_cmdsets(self.session, self.session, None, None, "session") + _callback = lambda cmdset: self.assertEqual(cmdset.key, "A") + deferred.addCallback(_callback) + return deferred + + def test_from_player(self): + self.set_cmdsets(self.player, self.cmdset_a) + deferred = cmdhandler.get_and_merge_cmdsets(self.player, None, self.player, None, "player") + # get_and_merge_cmdsets converts to lower-case internally. + _callback = lambda cmdset: self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4) + deferred.addCallback(_callback) + return deferred + + def test_from_object(self): + self.set_cmdsets(self.obj1, self.cmdset_a) + deferred = cmdhandler.get_and_merge_cmdsets(self.obj1, None, None, self.obj1, "object") + # get_and_merge_cmdsets converts to lower-case internally. + _callback = lambda cmdset: self.assertEqual(sum(1 for cmd in cmdset.commands if cmd.key in ("a", "b", "c", "d")), 4) + deferred.addCallback(_callback) + return deferred + + def test_multimerge(self): + a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d + d.no_exits = 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): + self.assertEqual(cmdset.key, "D") + self.assertTrue(cmdset.no_exits) + deferred.addCallback(_callback) + return deferred + + + + diff --git a/evennia/utils/test_resources.py b/evennia/utils/test_resources.py index c488e0723..03535551d 100644 --- a/evennia/utils/test_resources.py +++ b/evennia/utils/test_resources.py @@ -61,3 +61,6 @@ class EvenniaTest(TestCase): def tearDown(self): flush_cache() del SESSIONS[self.session.sessid] + self.player.delete() + self.player2.delete() + super(EvenniaTest, self).tearDown()