Add unit tests for syscmds, refactor cmdparser
This commit is contained in:
parent
55eb026e95
commit
11d39a57b5
4 changed files with 170 additions and 119 deletions
|
|
@ -20,6 +20,7 @@ the line is just added to the editor buffer).
|
|||
|
||||
from evennia.comms.models import ChannelDB
|
||||
from evennia.utils import create
|
||||
from evennia.utils.utils import at_search_result
|
||||
|
||||
# The command keys the engine is calling
|
||||
# (the actual names all start with __)
|
||||
|
|
@ -76,57 +77,30 @@ class SystemMultimatch(COMMAND_DEFAULT_CLASS):
|
|||
The cmdhandler adds a special attribute 'matches' to this
|
||||
system command.
|
||||
|
||||
matches = [(candidate, cmd) , (candidate, cmd), ...],
|
||||
matches = [(cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname) , (cmdname, ...), ...]
|
||||
|
||||
Here, `cmdname` is the command's name and `args` the rest of the incoming string,
|
||||
without said command name. `cmdobj` is the Command instance, the cmdlen is
|
||||
the same as len(cmdname) and mratio is a measure of how big a part of the
|
||||
full input string the cmdname takes up - an exact match would be 1.0. Finally,
|
||||
the `raw_cmdname` is the cmdname unmodified by eventual prefix-stripping.
|
||||
|
||||
where candidate is an instance of evennia.commands.cmdparser.CommandCandidate
|
||||
and cmd is an an instantiated Command object matching the candidate.
|
||||
"""
|
||||
key = CMD_MULTIMATCH
|
||||
locks = "cmd:all()"
|
||||
|
||||
def format_multimatches(self, caller, matches):
|
||||
"""
|
||||
Format multiple command matches to a useful error.
|
||||
|
||||
This is copied directly from the default method in
|
||||
evennia.commands.cmdhandler.
|
||||
|
||||
"""
|
||||
string = "There were multiple matches:"
|
||||
for num, match in enumerate(matches):
|
||||
# each match is a tuple (candidate, cmd)
|
||||
candidate, cmd = match
|
||||
|
||||
is_channel = hasattr(cmd, "is_channel") and cmd.is_channel
|
||||
if is_channel:
|
||||
is_channel = " (channel)"
|
||||
else:
|
||||
is_channel = ""
|
||||
is_exit = hasattr(cmd, "is_exit") and cmd.is_exit
|
||||
if is_exit and cmd.destination:
|
||||
is_exit = " (exit to %s)" % cmd.destination
|
||||
else:
|
||||
is_exit = ""
|
||||
|
||||
id1 = ""
|
||||
id2 = ""
|
||||
if not (is_channel or is_exit) and (hasattr(cmd, 'obj') and cmd.obj != caller):
|
||||
# the command is defined on some other object
|
||||
id1 = "%s-" % cmd.obj.name
|
||||
id2 = " (%s-%s)" % (num + 1, candidate.cmdname)
|
||||
else:
|
||||
id1 = "%s-" % (num + 1)
|
||||
id2 = ""
|
||||
string += "\n %s%s%s%s%s" % (id1, candidate.cmdname, id2, is_channel, is_exit)
|
||||
return string
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
argument to cmd is a comma-separated string of
|
||||
all the clashing matches.
|
||||
Handle multiple-matches by using the at_search_result default handler.
|
||||
|
||||
"""
|
||||
string = self.format_multimatches(self.caller, self.matches)
|
||||
self.msg(string)
|
||||
# this was set by the cmdparser and is a tuple
|
||||
# (cmdname, args, cmdobj, cmdlen, mratio, raw_cmdname). See
|
||||
# evennia.commands.cmdparse.create_match for more details.
|
||||
matches = self.matches
|
||||
# at_search_result will itself msg the multimatch options to the caller.
|
||||
at_search_result(
|
||||
[match[2] for match in matches], self.caller, query=matches[0][0])
|
||||
|
||||
|
||||
# Command called when the command given at the command line
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@ from mock import Mock, mock
|
|||
|
||||
from evennia.commands.default.cmdset_character import CharacterCmdSet
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
from evennia.commands.default import help, general, system, admin, account, building, batchprocess, comms, unloggedin
|
||||
from evennia.commands.default import help, general, system, admin, account, building, batchprocess, comms, unloggedin, syscommands
|
||||
from evennia.commands.cmdparser import build_matches
|
||||
from evennia.commands.default.muxcommand import MuxCommand
|
||||
from evennia.commands.command import Command, InterruptCommand
|
||||
from evennia.commands import cmdparser
|
||||
from evennia.commands.cmdset import CmdSet
|
||||
from evennia.utils import ansi, utils, gametime
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia import search_object
|
||||
|
|
@ -283,30 +286,30 @@ class TestAccount(CommandTest):
|
|||
def test_char_create(self):
|
||||
self.call(account.CmdCharCreate(), "Test1=Test char",
|
||||
"Created new character Test1. Use @ic Test1 to enter the game", caller=self.account)
|
||||
|
||||
|
||||
def test_char_delete(self):
|
||||
# Chardelete requires user input; this test is mainly to confirm
|
||||
# Chardelete requires user input; this test is mainly to confirm
|
||||
# whether permissions are being checked
|
||||
|
||||
|
||||
# Add char to account playable characters
|
||||
self.account.db._playable_characters.append(self.char1)
|
||||
|
||||
|
||||
# Try deleting as Developer
|
||||
self.call(account.CmdCharDelete(), "Char", "This will permanently destroy 'Char'. This cannot be undone. Continue yes/[no]?", caller=self.account)
|
||||
|
||||
|
||||
# Downgrade permissions on account
|
||||
self.account.permissions.add('Player')
|
||||
self.account.permissions.remove('Developer')
|
||||
|
||||
|
||||
# Set lock on character object to prevent deletion
|
||||
self.char1.locks.add('delete:none()')
|
||||
|
||||
|
||||
# Try deleting as Player
|
||||
self.call(account.CmdCharDelete(), "Char", "You do not have permission to delete this character.", caller=self.account)
|
||||
|
||||
|
||||
# Set lock on character object to allow self-delete
|
||||
self.char1.locks.add('delete:pid(%i)' % self.account.id)
|
||||
|
||||
|
||||
# Try deleting as Player again
|
||||
self.call(account.CmdCharDelete(), "Char", "This will permanently destroy 'Char'. This cannot be undone. Continue yes/[no]?", caller=self.account)
|
||||
|
||||
|
|
@ -657,3 +660,33 @@ class TestUnconnectedCommand(CommandTest):
|
|||
datetime.datetime.fromtimestamp(gametime.SERVER_START_TIME).ctime(),
|
||||
SESSIONS.account_count(), utils.get_evennia_version())
|
||||
self.call(unloggedin.CmdUnconnectedInfo(), "", expected)
|
||||
|
||||
|
||||
# Test syscommands
|
||||
|
||||
class TestSystemCommands(CommandTest):
|
||||
|
||||
def test_simple_defaults(self):
|
||||
self.call(syscommands.SystemNoInput(), "")
|
||||
self.call(syscommands.SystemNoMatch(), "Huh?")
|
||||
|
||||
def test_multimatch(self):
|
||||
# set up fake matches and store on command instance
|
||||
cmdset = CmdSet()
|
||||
cmdset.add(general.CmdLook())
|
||||
cmdset.add(general.CmdLook())
|
||||
matches = cmdparser.build_matches("look", cmdset)
|
||||
|
||||
multimatch = syscommands.SystemMultimatch()
|
||||
multimatch.matches = matches
|
||||
|
||||
self.call(multimatch, "look", "")
|
||||
|
||||
@mock.patch("evennia.commands.default.syscommands.ChannelDB")
|
||||
def test_channelcommand(self, mock_channeldb):
|
||||
channel = mock.MagicMock()
|
||||
channel.msg = mock.MagicMock()
|
||||
mock_channeldb.objects.get_channel = mock.MagicMock(return_value=channel)
|
||||
|
||||
self.call(syscommands.SystemSendToChannel(), "public:Hello")
|
||||
channel.msg.assert_called()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue