Fix unittests

This commit is contained in:
Griatch 2018-07-21 13:40:46 +02:00
parent 7ac113a3e1
commit 5db7c1dfbb
5 changed files with 128 additions and 60 deletions

View file

@ -2993,22 +2993,22 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
try:
prot = protlib.save_prototype(**prototype)
if not prot:
caller.msg("|rError saving:|R {}.|n".format(key))
caller.msg("|rError saving:|R {}.|n".format(prototype_key))
return
except PermissionError as err:
except protlib.PermissionError as err:
caller.msg("|rError saving:|R {}|n".format(err))
return
caller.msg("|gSaved prototype:|n {}".format(key))
caller.msg("|gSaved prototype:|n {}".format(prototype_key))
# check if we want to update existing objects
existing_objects = spawner.search_objects_with_prototype(key)
existing_objects = protlib.search_objects_with_prototype(prototype_key)
if existing_objects:
if 'update' not in self.switches:
n_existing = len(existing_objects)
slow = " (note that this may be slow)" if n_existing > 10 else ""
string = ("There are {} objects already created with an older version "
"of prototype {}. Should it be re-applied to them{}? [Y]/N".format(
n_existing, key, slow))
n_existing, prototype_key, slow))
answer = yield(string)
if answer.lower() in ["n", "no"]:
caller.msg("|rNo update was done of existing objects. "
@ -3036,7 +3036,7 @@ class CmdSpawn(COMMAND_DEFAULT_CLASS):
return
try:
success = protlib.delete_db_prototype(caller, self.args)
except PermissionError as err:
except protlib.PermissionError as err:
caller.msg("|rError deleting:|R {}|n".format(err))
caller.msg("Deletion {}.".format(
'successful' if success else 'failed (does the prototype exist?)'))

View file

@ -28,7 +28,7 @@ from evennia.utils import ansi, utils, gametime
from evennia.server.sessionhandler import SESSIONS
from evennia import search_object
from evennia import DefaultObject, DefaultCharacter
from evennia.prototypes import spawner, prototypes as protlib
from evennia.prototypes import prototypes as protlib
# set up signal here since we are not starting the server
@ -46,7 +46,7 @@ class CommandTest(EvenniaTest):
Tests a command
"""
def call(self, cmdobj, args, msg=None, cmdset=None, noansi=True, caller=None,
receiver=None, cmdstring=None, obj=None):
receiver=None, cmdstring=None, obj=None, inputs=None):
"""
Test a command by assigning all the needed
properties to cmdobj and running
@ -75,14 +75,31 @@ class CommandTest(EvenniaTest):
cmdobj.obj = obj or (caller if caller else self.char1)
# test
old_msg = receiver.msg
inputs = inputs or []
try:
receiver.msg = Mock()
if cmdobj.at_pre_cmd():
return
cmdobj.parse()
ret = cmdobj.func()
# handle func's with yield in them (generators)
if isinstance(ret, types.GeneratorType):
ret.next()
while True:
try:
inp = inputs.pop() if inputs else None
if inp:
try:
ret.send(inp)
except TypeError:
ret.next()
ret = ret.send(inp)
else:
ret.next()
except StopIteration:
break
cmdobj.at_post_cmd()
except StopIteration:
pass
@ -95,7 +112,7 @@ class CommandTest(EvenniaTest):
# Get the first element of a tuple if msg received a tuple instead of a string
stored_msg = [smsg[0] if isinstance(smsg, tuple) else smsg for smsg in stored_msg]
if msg is not None:
returned_msg = "||".join(_RE.sub("", mess) for mess in stored_msg)
returned_msg = "||".join(_RE.sub("", str(mess)) for mess in stored_msg)
returned_msg = ansi.parse_ansi(returned_msg, strip_ansi=noansi).strip()
if msg == "" and returned_msg or not returned_msg.startswith(msg.strip()):
sep1 = "\n" + "=" * 30 + "Wanted message" + "=" * 34 + "\n"
@ -369,13 +386,13 @@ class TestBuilding(CommandTest):
self.call(building.CmdSpawn(), " ", "Usage: @spawn")
# Tests "@spawn <prototype_dictionary>" without specifying location.
with mock.patch('evennia.commands.default.func', return_value=iter(['y'])) as mock_iter:
self.call(building.CmdSpawn(),
"/save {'prototype_key': 'testprot', 'key':'Test Char', "
"'typeclass':'evennia.objects.objects.DefaultCharacter'}", "")
mock_iter.assert_called()
self.call(building.CmdSpawn(), "/list", "foo")
self.call(building.CmdSpawn(),
"/save {'prototype_key': 'testprot', 'key':'Test Char', "
"'typeclass':'evennia.objects.objects.DefaultCharacter'}",
"Saved prototype: testprot", inputs=['y'])
self.call(building.CmdSpawn(), "/list", "| Key ")
self.call(building.CmdSpawn(), 'testprot', "Spawned Test Char")
# Tests that the spawned object's location is the same as the caharacter's location, since
@ -401,10 +418,14 @@ class TestBuilding(CommandTest):
goblin.delete()
protlib.create_prototype(**{'key': 'Ball', 'prototype': 'GOBLIN', 'prototype_key': 'testball'})
# create prototype
protlib.create_prototype(**{'key': 'Ball',
'typeclass': 'evennia.objects.objects.DefaultCharacter',
'prototype_key': 'testball'})
# Tests "@spawn <prototype_name>"
self.call(building.CmdSpawn(), "testball", "Spawned Ball")
ball = getObject(self, "Ball")
self.assertEqual(ball.location, self.char1.location)
self.assertIsInstance(ball, DefaultObject)
@ -417,10 +438,14 @@ class TestBuilding(CommandTest):
self.assertIsNone(ball.location)
ball.delete()
self.call(building.CmdSpawn(),
"/noloc {'prototype_parent':'TESTBALL', 'prototype_key': 'testball', 'location':'%s'}"
% spawnLoc.dbref, "Error: Prototype testball tries to parent itself.")
# Tests "@spawn/noloc ...", but DO specify a location.
# Location should be the specified location.
self.call(building.CmdSpawn(),
"/noloc {'prototype':'TESTBALL', 'location':'%s'}"
"/noloc {'prototype_parent':'TESTBALL', 'key': 'Ball', 'prototype_key': 'foo', 'location':'%s'}"
% spawnLoc.dbref, "Spawned Ball")
ball = getObject(self, "Ball")
self.assertEqual(ball.location, spawnLoc)

View file

@ -905,19 +905,19 @@ WEAPON_PROTOTYPES = {
"magic": False,
"desc": "A generic blade."},
"knife": {
"prototype": "weapon",
"prototype_parent": "weapon",
"aliases": "sword",
"key": "Kitchen knife",
"desc": "A rusty kitchen knife. Better than nothing.",
"damage": 3},
"dagger": {
"prototype": "knife",
"prototype_parent": "knife",
"key": "Rusty dagger",
"aliases": ["knife", "dagger"],
"desc": "A double-edged dagger with a nicked edge and a wooden handle.",
"hit": 0.25},
"sword": {
"prototype": "weapon",
"prototype_parent": "weapon",
"key": "Rusty sword",
"aliases": ["sword"],
"desc": "A rusty shortsword. It has a leather-wrapped handle covered i food grease.",
@ -925,28 +925,28 @@ WEAPON_PROTOTYPES = {
"damage": 5,
"parry": 0.5},
"club": {
"prototype": "weapon",
"prototype_parent": "weapon",
"key": "Club",
"desc": "A heavy wooden club, little more than a heavy branch.",
"hit": 0.4,
"damage": 6,
"parry": 0.2},
"axe": {
"prototype": "weapon",
"prototype_parent": "weapon",
"key": "Axe",
"desc": "A woodcutter's axe with a keen edge.",
"hit": 0.4,
"damage": 6,
"parry": 0.2},
"ornate longsword": {
"prototype": "sword",
"prototype_parent": "sword",
"key": "Ornate longsword",
"desc": "A fine longsword with some swirling patterns on the handle.",
"hit": 0.5,
"magic": True,
"damage": 5},
"warhammer": {
"prototype": "club",
"prototype_parent": "club",
"key": "Silver Warhammer",
"aliases": ["hammer", "warhammer", "war"],
"desc": "A heavy war hammer with silver ornaments. This huge weapon causes massive damage - if you can hit.",
@ -954,21 +954,21 @@ WEAPON_PROTOTYPES = {
"magic": True,
"damage": 8},
"rune axe": {
"prototype": "axe",
"prototype_parent": "axe",
"key": "Runeaxe",
"aliases": ["axe"],
"hit": 0.4,
"magic": True,
"damage": 6},
"thruning": {
"prototype": "ornate longsword",
"prototype_parent": "ornate longsword",
"key": "Broadsword named Thruning",
"desc": "This heavy bladed weapon is marked with the name 'Thruning'. It is very powerful in skilled hands.",
"hit": 0.6,
"parry": 0.6,
"damage": 7},
"slayer waraxe": {
"prototype": "rune axe",
"prototype_parent": "rune axe",
"key": "Slayer waraxe",
"aliases": ["waraxe", "war", "slayer"],
"desc": "A huge double-bladed axe marked with the runes for 'Slayer'."
@ -976,7 +976,7 @@ WEAPON_PROTOTYPES = {
"hit": 0.7,
"damage": 8},
"ghostblade": {
"prototype": "ornate longsword",
"prototype_parent": "ornate longsword",
"key": "The Ghostblade",
"aliases": ["blade", "ghost"],
"desc": "This massive sword is large as you are tall, yet seems to weigh almost nothing."
@ -985,7 +985,7 @@ WEAPON_PROTOTYPES = {
"parry": 0.8,
"damage": 10},
"hawkblade": {
"prototype": "ghostblade",
"prototype_parent": "ghostblade",
"key": "The Hawkblade",
"aliases": ["hawk", "blade"],
"desc": "The weapon of a long-dead heroine and a more civilized age,"

View file

@ -13,7 +13,7 @@ from evennia.objects.models import ObjectDB
from evennia.utils.create import create_script
from evennia.utils.utils import (
all_from_module, make_iter, is_iter, dbid_to_obj, callables_from_module,
get_all_typeclasses, to_str)
get_all_typeclasses, to_str, dbref)
from evennia.locks.lockhandler import validate_lockstring, check_lockstring
from evennia.utils import logger
from evennia.utils import inlinefuncs
@ -91,6 +91,10 @@ def protfunc_parser(value, available_functions=None, testing=False, stacktrace=F
"""
if not isinstance(value, basestring):
try:
value = value.dbref
except AttributeError:
pass
value = to_str(value, force_string=True)
available_functions = _PROT_FUNCS if available_functions is None else available_functions
@ -577,7 +581,7 @@ def validate_prototype(prototype, protkey=None, protparents=None,
for protstring in make_iter(prototype_parent):
protstring = protstring.lower()
if protkey is not None and protstring == protkey:
_flags['errors'].append("Protototype {} tries to parent itself.".format(protkey))
_flags['errors'].append("Prototype {} tries to parent itself.".format(protkey))
protparent = protparents.get(protstring)
if not protparent:
_flags['errors'].append("Prototype {}'s prototype_parent '{}' was not found.".format(
@ -610,7 +614,7 @@ def validate_prototype(prototype, protkey=None, protparents=None,
# make sure prototype_locks are set to defaults
prototype_locks = [lstring.split(":", 1)
for lstring in prototype.get("prototype_locks", "").split(';')]
for lstring in prototype.get("prototype_locks", "").split(';') if ":" in lstring]
locktypes = [tup[0].strip() for tup in prototype_locks]
if "spawn" not in locktypes:
prototype_locks.append(("spawn", "all()"))

View file

@ -114,24 +114,41 @@ class TestUtils(EvenniaTest):
self.assertEqual(
pdiff,
{'aliases': 'REMOVE',
'attrs': 'REPLACE',
'home': 'KEEP',
'key': 'UPDATE',
'location': 'KEEP',
'locks': 'KEEP',
'new': 'UPDATE',
'permissions': 'UPDATE',
'prototype_desc': 'UPDATE',
'prototype_key': 'UPDATE',
'prototype_locks': 'KEEP',
'prototype_tags': 'KEEP',
'test': 'UPDATE',
'typeclass': 'KEEP'})
({'aliases': 'REMOVE',
'attrs': 'REPLACE',
'home': 'KEEP',
'key': 'UPDATE',
'location': 'KEEP',
'locks': 'KEEP',
'new': 'UPDATE',
'permissions': 'UPDATE',
'prototype_desc': 'UPDATE',
'prototype_key': 'UPDATE',
'prototype_locks': 'KEEP',
'prototype_tags': 'KEEP',
'test': 'UPDATE',
'typeclass': 'KEEP'},
{'attrs': [('oldtest', 'to_remove', None, ['']),
('test', 'testval', None, [''])],
'prototype_locks': 'spawn:all();edit:all()',
'prototype_key': Something,
'locks': ['call:true()', 'control:perm(Developer)',
'delete:perm(Admin)', 'edit:perm(Admin)',
'examine:perm(Builder)', 'get:all()',
'puppet:pperm(Developer)', 'tell:perm(Admin)',
'view:all()'],
'prototype_tags': [],
'location': self.room1,
'key': 'NewObj',
'home': self.room1,
'typeclass': 'evennia.objects.objects.DefaultObject',
'prototype_desc': 'Built from NewObj',
'aliases': 'foo'})
)
# apply diff
count = spawner.batch_update_objects_with_prototype(
old_prot, diff=pdiff, objects=[self.obj1])
old_prot, diff=pdiff[0], objects=[self.obj1])
self.assertEqual(count, 1)
new_prot = spawner.prototype_from_object(self.obj1)
@ -470,7 +487,7 @@ class TestOLCMenu(TestEvMenu):
menutree = "evennia.prototypes.menus"
startnode = "node_index"
debug_output = True
# debug_output = True
expect_all_nodes = True
expected_node_texts = {
@ -480,15 +497,37 @@ class TestOLCMenu(TestEvMenu):
expected_tree = \
['node_index',
['node_prototype_key',
['node_index',
'node_index',
'node_validate_prototype',
['node_index'],
'node_index'],
'node_typeclass',
'node_aliases',
'node_attrs',
'node_tags',
'node_locks',
'node_permissions',
'node_location',
'node_home',
'node_destination',
'node_prototype_desc',
'node_prototype_tags',
'node_prototype_locks']]
['node_key',
['node_typeclass',
'node_key',
'node_index',
'node_validate_prototype',
'node_validate_prototype'],
'node_index',
'node_index',
'node_index',
'node_validate_prototype',
'node_validate_prototype'],
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype',
'node_validate_prototype']]