mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
1197 lines
44 KiB
Python
1197 lines
44 KiB
Python
"""
|
|
Unit testing for the Command system itself.
|
|
|
|
"""
|
|
|
|
from django.test import override_settings
|
|
from evennia.utils.test_resources import EvenniaTest, TestCase
|
|
from evennia.commands.cmdset import CmdSet
|
|
from evennia.commands.command import Command
|
|
from evennia.commands import cmdparser
|
|
|
|
|
|
# Testing-command sets
|
|
|
|
|
|
class _CmdA(Command):
|
|
key = "A"
|
|
|
|
def __init__(self, cmdset, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.from_cmdset = cmdset
|
|
|
|
|
|
class _CmdB(Command):
|
|
key = "B"
|
|
|
|
def __init__(self, cmdset, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.from_cmdset = cmdset
|
|
|
|
|
|
class _CmdC(Command):
|
|
key = "C"
|
|
|
|
def __init__(self, cmdset, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.from_cmdset = cmdset
|
|
|
|
|
|
class _CmdD(Command):
|
|
key = "D"
|
|
|
|
def __init__(self, cmdset, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.from_cmdset = cmdset
|
|
|
|
|
|
class _CmdSetA(CmdSet):
|
|
key = "A"
|
|
|
|
def at_cmdset_creation(self):
|
|
self.add(_CmdA("A"))
|
|
self.add(_CmdB("A"))
|
|
self.add(_CmdC("A"))
|
|
self.add(_CmdD("A"))
|
|
|
|
|
|
class _CmdSetB(CmdSet):
|
|
key = "B"
|
|
|
|
def at_cmdset_creation(self):
|
|
self.add(_CmdA("B"))
|
|
self.add(_CmdB("B"))
|
|
self.add(_CmdC("B"))
|
|
|
|
|
|
class _CmdSetC(CmdSet):
|
|
key = "C"
|
|
|
|
def at_cmdset_creation(self):
|
|
self.add(_CmdA("C"))
|
|
self.add(_CmdB("C"))
|
|
|
|
|
|
class _CmdSetD(CmdSet):
|
|
key = "D"
|
|
|
|
def at_cmdset_creation(self):
|
|
self.add(_CmdA("D"))
|
|
self.add(_CmdB("D"))
|
|
self.add(_CmdC("D"))
|
|
self.add(_CmdD("D"))
|
|
|
|
|
|
# testing Command Sets
|
|
|
|
|
|
class TestCmdSetMergers(TestCase):
|
|
"Test merging of cmdsets"
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.cmdset_a = _CmdSetA()
|
|
self.cmdset_b = _CmdSetB()
|
|
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
|
|
cmdset_f = d + c + b + a # merge in reverse order of priority
|
|
self.assertEqual(cmdset_f.priority, 0)
|
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
|
cmdset_f = a + b + c + d # merge in order of priority
|
|
self.assertEqual(cmdset_f.priority, 0)
|
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
|
self.assertEqual(len(cmdset_f.commands), 4) # duplicates setting from A transfers
|
|
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "D"))
|
|
|
|
def test_priority_order(self):
|
|
"Merge in reverse- and forward order with well-defined prioritities"
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
cmdset_f = d + c + b + a # merge in reverse order of priority
|
|
self.assertEqual(cmdset_f.priority, 2)
|
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
|
cmdset_f = a + b + c + d # merge in order of priority
|
|
self.assertEqual(cmdset_f.priority, 2)
|
|
self.assertEqual(cmdset_f.mergetype, "Union")
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
self.assertTrue(all(True for cmd in cmdset_f.commands if cmd.from_cmdset == "A"))
|
|
|
|
|
|
class TestOptionTransferTrue(TestCase):
|
|
"""
|
|
Test cmdset-merge transfer of the cmdset-special options
|
|
(no_exits/channels/objs/duplicates etc)
|
|
|
|
cmdset A has all True options
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.cmdset_a = _CmdSetA()
|
|
self.cmdset_b = _CmdSetB()
|
|
self.cmdset_c = _CmdSetC()
|
|
self.cmdset_d = _CmdSetD()
|
|
self.cmdset_a.priority = 0
|
|
self.cmdset_b.priority = 0
|
|
self.cmdset_c.priority = 0
|
|
self.cmdset_d.priority = 0
|
|
self.cmdset_a.no_exits = True
|
|
self.cmdset_a.no_objs = True
|
|
self.cmdset_a.no_channels = True
|
|
self.cmdset_a.duplicates = True
|
|
|
|
def test_option_transfer__reverse_sameprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges last (normal reverse merge), same prio.
|
|
The options should pass through to F since none of the other cmdsets
|
|
care to change the setting from their default None.
|
|
|
|
Since A.duplicates = True, the final result is an union of duplicate
|
|
pairs (8 commands total).
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
cmdset_f = d + c + b + a # reverse, same-prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 8)
|
|
|
|
def test_option_transfer__forward_sameprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges first (forward merge), same prio. This
|
|
should pass those options through since the other all have options set
|
|
to None. The exception is `duplicates` since that is determined by
|
|
the two last mergers in the chain both being True.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
cmdset_f = a + b + c + d # forward, same-prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_highprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges last (normal reverse merge) with the
|
|
highest prio. This should also pass through.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
cmdset_f = d + c + b + a # reverse, A top priority
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_highprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges first (forward merge). This is a bit
|
|
synthetic since it will never happen in practice, but logic should
|
|
still make it pass through.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
cmdset_f = a + b + c + d # forward, A top priority. This never happens in practice.
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_lowprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges last (normal reverse merge) with the lowest
|
|
prio. This never happens (it would always merge first) but logic should hold
|
|
and pass through since the other cmdsets have None.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
cmdset_f = d + c + b + a # reverse, A low prio. This never happens in practice.
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_passthrough(self):
|
|
"""
|
|
A has all True options, merges first (forward merge) with lowest prio. This
|
|
is the normal behavior for a low-prio cmdset. Passthrough should happen.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_highprio_block_passthrough(self):
|
|
"""
|
|
A has all True options, other cmdsets has False. A merges last with high
|
|
prio. A should retain its option values and override the others
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
c.no_exits = False
|
|
b.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, high prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_highprio_block_passthrough(self):
|
|
"""
|
|
A has all True options, other cmdsets has False. A merges last with high
|
|
prio. This situation should never happen, but logic should hold - the highest
|
|
prio's options should survive the merge process.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
c.no_exits = False
|
|
b.no_channels = False
|
|
b.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, high prio, never happens
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_block(self):
|
|
"""
|
|
A has all True options, other cmdsets has False. A merges last with low
|
|
prio. This should result in its values being blocked and come out False.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = False
|
|
c.no_channels = False
|
|
b.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_block_partial(self):
|
|
"""
|
|
A has all True options, other cmdsets has False excet C which has a None
|
|
for `no_channels`. A merges last with low
|
|
prio. This should result in its values being blocked and come out False
|
|
except for no_channels which passes through.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = False
|
|
c.no_channels = None # passthrough
|
|
b.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_highprio_sameprio_order_last(self):
|
|
"""
|
|
A has all True options and highest prio, D has False and lowest prio,
|
|
others are passthrough. B has the same prio as A, with passthrough.
|
|
|
|
Since A is merged last, this should give prio to A's options
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
d.priority = -1
|
|
d.no_channels = False
|
|
d.no_exits = False
|
|
d.no_objs = None
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, A same prio, merged after b
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 8)
|
|
|
|
def test_option_transfer__reverse_highprio_sameprio_order_first(self):
|
|
"""
|
|
A has all True options and highest prio, D has False and lowest prio,
|
|
others are passthrough. B has the same prio as A, with passthrough.
|
|
|
|
While B, with None-values, is merged after A, A's options should have
|
|
replaced those of D at that point, and since B has passthrough the
|
|
final result should contain A's True options.
|
|
|
|
Note that despite A having duplicates=True, there is no duplication in
|
|
the DB + A merger since they have different priorities.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
d.priority = -1
|
|
d.no_channels = False
|
|
d.no_exits = False
|
|
d.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + a + b # reverse, A same prio, merged before b
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_lowprio_block(self):
|
|
"""
|
|
A has all True options, other cmdsets has False. A merges last with low
|
|
prio. This usually doesn't happen- it should merge last. But logic should
|
|
hold and the low-prio cmdset's values should be blocked and come out False.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = False
|
|
d.no_channels = False
|
|
b.no_objs = False
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, A low prio, never happens
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
|
|
class TestOptionTransferFalse(TestCase):
|
|
"""
|
|
Test cmdset-merge transfer of the cmdset-special options
|
|
(no_exits/channels/objs/duplicates etc)
|
|
|
|
cmdset A has all False options
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.cmdset_a = _CmdSetA()
|
|
self.cmdset_b = _CmdSetB()
|
|
self.cmdset_c = _CmdSetC()
|
|
self.cmdset_d = _CmdSetD()
|
|
self.cmdset_a.priority = 0
|
|
self.cmdset_b.priority = 0
|
|
self.cmdset_c.priority = 0
|
|
self.cmdset_d.priority = 0
|
|
self.cmdset_a.no_exits = False
|
|
self.cmdset_a.no_objs = False
|
|
self.cmdset_a.no_channels = False
|
|
self.cmdset_a.duplicates = False
|
|
|
|
def test_option_transfer__reverse_sameprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges last (normal reverse merge), same prio.
|
|
The options should pass through to F since none of the other cmdsets
|
|
care to change the setting from their default None.
|
|
|
|
Since A has duplicates=False, the result is a unique union of 4 cmds.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
cmdset_f = d + c + b + a # reverse, same-prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_sameprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges first (forward merge), same prio. This
|
|
should pass those options through since the other all have options set
|
|
to None. The exception is `duplicates` since that is determined by
|
|
the two last mergers in the chain both being .
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
cmdset_f = a + b + c + d # forward, same-prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_highprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges last (normal reverse merge) with the
|
|
highest prio. This should also pass through.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
cmdset_f = d + c + b + a # reverse, A top priority
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_highprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges first (forward merge). This is a bit
|
|
synthetic since it will never happen in practice, but logic should
|
|
still make it pass through.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
cmdset_f = a + b + c + d # forward, A top priority. This never happens in practice.
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_lowprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges last (normal reverse merge) with the lowest
|
|
prio. This never happens (it would always merge first) but logic should hold
|
|
and pass through since the other cmdsets have None.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
cmdset_f = d + c + b + a # reverse, A low prio. This never happens in practice.
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_passthrough(self):
|
|
"""
|
|
A has all False options, merges first (forward merge) with lowest prio. This
|
|
is the normal behavior for a low-prio cmdset. Passthrough should happen.
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_highprio_block_passthrough(self):
|
|
"""
|
|
A has all False options, other cmdsets has True. A merges last with high
|
|
prio. A should retain its option values and override the others
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
c.no_exits = True
|
|
b.no_objs = True
|
|
d.duplicates = True
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, high prio
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_highprio_block_passthrough(self):
|
|
"""
|
|
A has all False options, other cmdsets has True. A merges last with high
|
|
prio. This situation should never happen, but logic should hold - the highest
|
|
prio's options should survive the merge process.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 1
|
|
c.priority = 0
|
|
d.priority = -1
|
|
c.no_exits = True
|
|
b.no_channels = True
|
|
b.no_objs = True
|
|
d.duplicates = True
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, high prio, never happens
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_block(self):
|
|
"""
|
|
A has all False options, other cmdsets has True. A merges last with low
|
|
prio. This should result in its values being blocked and come out False.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = True
|
|
c.no_channels = True
|
|
b.no_objs = True
|
|
d.duplicates = True
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__forward_lowprio_block_partial(self):
|
|
"""
|
|
A has all False options, other cmdsets has True excet C which has a None
|
|
for `no_channels`. A merges last with low
|
|
prio. This should result in its values being blocked and come out True
|
|
except for no_channels which passes through.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = True
|
|
c.no_channels = None # passthrough
|
|
b.no_objs = True
|
|
d.duplicates = True
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = a + b + c + d # forward, A low prio
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_sameprio_order_last(self):
|
|
"""
|
|
A has all False options and highest prio, D has True and lowest prio,
|
|
others are passthrough. B has the same prio as A, with passthrough.
|
|
|
|
Since A is merged last, this should give prio to A's False options
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
d.priority = -1
|
|
d.no_channels = True
|
|
d.no_exits = True
|
|
d.no_objs = True
|
|
d.duplicates = False
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, A high prio, merged after b
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_sameprio_order_first(self):
|
|
"""
|
|
A has all False options and highest prio, D has True and lowest prio,
|
|
others are passthrough. B has the same prio as A, with passthrough.
|
|
|
|
While B, with None-values, is merged after A, A's options should have
|
|
replaced those of D at that point, and since B has passthrough the
|
|
final result should contain A's False options.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
d.priority = -1
|
|
d.no_channels = True
|
|
d.no_exits = True
|
|
d.no_objs = True
|
|
d.duplicates = False
|
|
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + a + b # reverse, A high prio, merged before b
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
def test_option_transfer__reverse_lowprio_block(self):
|
|
"""
|
|
A has all False options, other cmdsets has True. A merges last with low
|
|
prio. This usually doesn't happen- it should merge last. But logic should
|
|
hold and the low-prio cmdset's values should be blocked and come out True.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = -1
|
|
b.priority = 0
|
|
c.priority = 1
|
|
d.priority = 2
|
|
c.no_exits = True
|
|
d.no_channels = True
|
|
b.no_objs = True
|
|
d.duplicates = True
|
|
# higher-prio sets will change the option up the chain
|
|
cmdset_f = d + c + b + a # reverse, A low prio, never happens
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
|
|
class TestDuplicateBehavior(TestCase):
|
|
"""
|
|
Test behavior of .duplicate option, which is a bit special in that it
|
|
doesn't propagate.
|
|
|
|
`A.duplicates=True` for all tests.
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.cmdset_a = _CmdSetA()
|
|
self.cmdset_b = _CmdSetB()
|
|
self.cmdset_c = _CmdSetC()
|
|
self.cmdset_d = _CmdSetD()
|
|
self.cmdset_a.priority = 0
|
|
self.cmdset_b.priority = 0
|
|
self.cmdset_c.priority = 0
|
|
self.cmdset_d.priority = 0
|
|
self.cmdset_a.duplicates = True
|
|
|
|
def test_reverse_sameprio_duplicate(self):
|
|
"""
|
|
Test of `duplicates` transfer which does not propagate. Only
|
|
A has duplicates=True.
|
|
|
|
D + B = DB (no duplication, DB.duplication=None)
|
|
DB + C = DBC (no duplication, DBC.duplication=None)
|
|
DBC + A = final (duplication, final.duplication=None)
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
cmdset_f = d + b + c + a # two last mergers duplicates=True
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 8)
|
|
|
|
def test_reverse_sameprio_duplicate(self):
|
|
"""
|
|
Test of `duplicates` transfer, which does not propagate.
|
|
C.duplication=True
|
|
|
|
D + B = DB (no duplication, DB.duplication=None)
|
|
DB + C = DBC (duplication, DBC.duplication=None)
|
|
DBC + A = final (duplication, final.duplication=None)
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
c.duplicates = True
|
|
cmdset_f = d + b + c + a # two last mergers duplicates=True
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 10)
|
|
|
|
def test_forward_sameprio_duplicate(self):
|
|
"""
|
|
Test of `duplicates` transfer which does not propagate.
|
|
C.duplication=True, merges later than A
|
|
|
|
D + B = DB (no duplication, DB.duplication=None)
|
|
DB + A = DBA (duplication, DBA.duplication=None)
|
|
DBA + C = final (duplication, final.duplication=None)
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
c.duplicates = True
|
|
cmdset_f = d + b + a + c # two last mergers duplicates=True
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 10)
|
|
|
|
def test_reverse_sameprio_duplicate_reverse(self):
|
|
"""
|
|
Test of `duplicates` transfer which does not propagate.
|
|
C.duplication=False (explicit), merges before A. This behavior is the
|
|
same as if C.duplication=None, since A merges later and takes
|
|
precedence.
|
|
|
|
D + B = DB (no duplication, DB.duplication=None)
|
|
DB + C = DBC (no duplication, DBC.duplication=None)
|
|
DBC + A = final (duplication, final.duplication=None)
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
c.duplicates = False
|
|
cmdset_f = d + b + c + a # a merges last, takes precedence
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 8)
|
|
|
|
def test_reverse_sameprio_duplicate_forward(self):
|
|
"""
|
|
Test of `duplicates` transfer which does not propagate.
|
|
C.duplication=False (explicit), merges after A. This just means
|
|
only A causes duplicates, earlier in the chain.
|
|
|
|
D + B = DB (no duplication, DB.duplication=None)
|
|
DB + A = DBA (duplication, DBA.duplication=None)
|
|
DBA + C = final (no duplication, final.duplication=None)
|
|
|
|
Note that DBA has 8 cmds due to A merging onto DB with duplication,
|
|
but since C merges onto this with no duplication, the union will hold
|
|
6 commands, since C has two commands that replaces the 4 duplicates
|
|
with uniques copies from C.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
c.duplicates = False
|
|
cmdset_f = d + b + a + c # a merges before c
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 6)
|
|
|
|
|
|
class TestOptionTransferReplace(TestCase):
|
|
"""
|
|
Test option transfer through more complex merge types.
|
|
"""
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.cmdset_a = _CmdSetA()
|
|
self.cmdset_b = _CmdSetB()
|
|
self.cmdset_c = _CmdSetC()
|
|
self.cmdset_d = _CmdSetD()
|
|
self.cmdset_a.priority = 0
|
|
self.cmdset_b.priority = 0
|
|
self.cmdset_c.priority = 0
|
|
self.cmdset_d.priority = 0
|
|
self.cmdset_a.no_exits = True
|
|
self.cmdset_a.no_objs = True
|
|
self.cmdset_a.no_channels = True
|
|
self.cmdset_a.duplicates = True
|
|
|
|
def test_option_transfer__replace_reverse_highprio(self):
|
|
"""
|
|
A has all options True and highest priority. C has them False and is
|
|
Replace-type.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
c.mergetype = "Replace"
|
|
c.no_channels = False
|
|
c.no_exits = False
|
|
c.no_objs = False
|
|
c.duplicates = False
|
|
d.priority = -1
|
|
|
|
cmdset_f = d + c + b + a # reverse, A high prio, C Replace
|
|
self.assertTrue(cmdset_f.no_exits)
|
|
self.assertTrue(cmdset_f.no_objs)
|
|
self.assertTrue(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 7)
|
|
|
|
def test_option_transfer__replace_reverse_highprio_from_false(self):
|
|
"""
|
|
Inverse of previous test: A has all options False and highest priority.
|
|
C has them True and is Replace-type.
|
|
|
|
"""
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.no_exits = False
|
|
a.no_objs = False
|
|
a.no_channels = False
|
|
a.duplicates = False
|
|
|
|
a.priority = 2
|
|
b.priority = 2
|
|
c.priority = 0
|
|
c.mergetype = "Replace"
|
|
c.no_channels = True
|
|
c.no_exits = True
|
|
c.no_objs = True
|
|
c.duplicates = True
|
|
d.priority = -1
|
|
|
|
cmdset_f = d + c + b + a # reverse, A high prio, C Replace
|
|
self.assertFalse(cmdset_f.no_exits)
|
|
self.assertFalse(cmdset_f.no_objs)
|
|
self.assertFalse(cmdset_f.no_channels)
|
|
self.assertIsNone(cmdset_f.duplicates)
|
|
self.assertEqual(len(cmdset_f.commands), 4)
|
|
|
|
|
|
# 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().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):
|
|
a = self.cmdset_a
|
|
a.no_channels = True
|
|
self.set_cmdsets(self.session, a)
|
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
|
self.session, self.session, None, None, "session", ""
|
|
)
|
|
|
|
def _callback(cmdset):
|
|
self.assertEqual(cmdset.key, "A")
|
|
|
|
deferred.addCallback(_callback)
|
|
return deferred
|
|
|
|
def test_from_account(self):
|
|
from evennia.commands.default.cmdset_account import AccountCmdSet
|
|
|
|
a = self.cmdset_a
|
|
a.no_channels = True
|
|
self.set_cmdsets(self.account, a)
|
|
deferred = cmdhandler.get_and_merge_cmdsets(
|
|
self.account, None, self.account, None, "account", ""
|
|
)
|
|
# get_and_merge_cmdsets converts to lower-case internally.
|
|
|
|
def _callback(cmdset):
|
|
pcmdset = AccountCmdSet()
|
|
pcmdset.at_cmdset_creation()
|
|
pcmds = [cmd.key for cmd in pcmdset.commands] + ["a", "b", "c", "d"]
|
|
self.assertTrue(all(cmd.key in pcmds for cmd in cmdset.commands))
|
|
|
|
# _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.
|
|
|
|
def _callback(cmdset):
|
|
return 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
|
|
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):
|
|
self.assertTrue(cmdset.no_exits)
|
|
self.assertTrue(cmdset.no_channels)
|
|
self.assertEqual(cmdset.key, "D")
|
|
|
|
deferred.addCallback(_callback)
|
|
return deferred
|
|
|
|
def test_duplicates(self):
|
|
a, b, c, d = self.cmdset_a, self.cmdset_b, self.cmdset_c, self.cmdset_d
|
|
a.no_exits = True
|
|
a.no_channels = True
|
|
b.duplicates = True
|
|
d.duplicates = 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(len(cmdset.commands), 9)
|
|
|
|
deferred.addCallback(_callback)
|
|
return deferred
|
|
|
|
|
|
class AccessableCommand(Command):
|
|
def access(*args, **kwargs):
|
|
return True
|
|
|
|
|
|
class _CmdTest1(AccessableCommand):
|
|
key = "test1"
|
|
|
|
|
|
class _CmdTest2(AccessableCommand):
|
|
key = "another command"
|
|
|
|
|
|
class _CmdTest3(AccessableCommand):
|
|
key = "&the third command"
|
|
|
|
|
|
class _CmdTest4(AccessableCommand):
|
|
key = "test2"
|
|
|
|
|
|
class _CmdSetTest(CmdSet):
|
|
key = "test_cmdset"
|
|
|
|
def at_cmdset_creation(self):
|
|
self.add(_CmdTest1)
|
|
self.add(_CmdTest2)
|
|
self.add(_CmdTest3)
|
|
|
|
|
|
class TestCmdParser(TestCase):
|
|
def test_create_match(self):
|
|
class DummyCmd:
|
|
pass
|
|
|
|
dummy = DummyCmd()
|
|
|
|
self.assertEqual(
|
|
cmdparser.create_match("look at", "look at target", dummy, "look"),
|
|
("look at", " target", dummy, 7, 0.5, "look"),
|
|
)
|
|
|
|
@override_settings(CMD_IGNORE_PREFIXES="@&/+")
|
|
def test_build_matches(self):
|
|
a_cmdset = _CmdSetTest()
|
|
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "test1"][0]
|
|
|
|
# normal parsing
|
|
self.assertEqual(
|
|
cmdparser.build_matches("test1 rock", a_cmdset, include_prefixes=False),
|
|
[("test1", " rock", bcmd, 5, 0.5, "test1")],
|
|
)
|
|
|
|
# test prefix exclusion
|
|
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "another command"][0]
|
|
self.assertEqual(
|
|
cmdparser.build_matches(
|
|
"@another command smiles to me ", a_cmdset, include_prefixes=False
|
|
),
|
|
[("another command", " smiles to me ", bcmd, 15, 0.5, "another command")],
|
|
)
|
|
# test prefix exclusion on the cmd class
|
|
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "&the third command"][0]
|
|
self.assertEqual(
|
|
cmdparser.build_matches("the third command", a_cmdset, include_prefixes=False),
|
|
[("the third command", "", bcmd, 17, 1.0, "&the third command")],
|
|
)
|
|
|
|
@override_settings(SEARCH_MULTIMATCH_REGEX=r"(?P<number>[0-9]+)-(?P<name>.*)")
|
|
def test_num_differentiators(self):
|
|
self.assertEqual(cmdparser.try_num_differentiators("look me"), (None, None))
|
|
self.assertEqual(cmdparser.try_num_differentiators("look me-3"), (3, "look me"))
|
|
self.assertEqual(cmdparser.try_num_differentiators("look me-567"), (567, "look me"))
|
|
|
|
@override_settings(
|
|
SEARCH_MULTIMATCH_REGEX=r"(?P<number>[0-9]+)-(?P<name>.*)", CMD_IGNORE_PREFIXES="@&/+"
|
|
)
|
|
def test_cmdparser(self):
|
|
a_cmdset = _CmdSetTest()
|
|
bcmd = [cmd for cmd in a_cmdset.commands if cmd.key == "test1"][0]
|
|
|
|
self.assertEqual(
|
|
cmdparser.cmdparser("test1hello", a_cmdset, None),
|
|
[("test1", "hello", bcmd, 5, 0.5, "test1")],
|
|
)
|
|
|
|
|
|
class TestCmdSetNesting(EvenniaTest):
|
|
"""
|
|
Test 'nesting' of cmdsets by adding
|
|
"""
|
|
|
|
def test_nest(self):
|
|
|
|
class CmdA(Command):
|
|
key = "a"
|
|
|
|
def func(self):
|
|
self.msg(str(self.obj))
|
|
|
|
class CmdSetA(CmdSet):
|
|
def at_cmdset_creation(self):
|
|
self.add(CmdA)
|
|
|
|
class CmdSetB(CmdSet):
|
|
def at_cmdset_creation(self):
|
|
self.add(CmdSetA)
|
|
|
|
cmd = self.char1.cmdset.cmdset_stack[-1].commands[0]
|
|
self.assertEqual(cmd.obj, self.char1)
|