functional test for forced leave configuration.

functional test for forced leave after combat.
functional test for MAKE TEMP.
error handling for Lua function building.create().
reduce some errors to warnings.
initialize race.battle_flags correctly (when not created through XML).
re-initialize processor in case config has changed.
handle missing translation of combat status, with error message.
This commit is contained in:
Enno Rehling 2015-06-19 13:17:01 +02:00
parent e7bffb7533
commit 9b7a4e813b
11 changed files with 147 additions and 13 deletions

View File

@ -36,4 +36,3 @@ function test_read_ship()
s = ship.create(nil, "boat")
assert_not_nil(s)
end

View File

@ -7,3 +7,4 @@ require 'tests.pool'
require 'tests.regions'
require 'tests.settings'
require 'tests.study'
require 'tests.laws'

114
scripts/tests/laws.lua Normal file
View File

@ -0,0 +1,114 @@
require "lunit"
module("tests.laws", package.seeall, lunit.testcase)
function setup()
eressea.free_game()
conf = [[{
"races": {
"human" : {}
},
"terrains" : {
"plain": { "flags" : [ "land", "walk", "sail" ] }
},
"keywords" : {
"de": {
"attack" : "ATTACKIERE",
"maketemp" : "MACHETEMP",
"end" : "ENDE",
"recruit" : "REKRUTIERE"
}
},
"buildings" : {
"castle" : {}
}
}]]
eressea.config.reset()
eressea.config.parse(conf)
end
function test_force_leave_on()
local r = region.create(0, 0, "plain")
local f1 = faction.create("owner@eressea.de")
local f2 = faction.create("guest@eressea.de")
local u1 = unit.create(f1, r, 1)
local u2 = unit.create(f2, r, 1)
local b1 = building.create(r, "castle")
u1.building = b1
u2.building = b1
eressea.settings.set("rules.owners.force_leave", "2")
process_orders()
assert_equal(b1, u1.building)
assert_equal(nil, u2.building)
end
function test_force_leave_off()
local r = region.create(0, 0, "plain")
local f1 = faction.create("owner@eressea.de")
local f2 = faction.create("guest@eressea.de")
local u1 = unit.create(f1, r, 1)
local u2 = unit.create(f2, r, 1)
local b1 = building.create(r, "castle")
u1.building = b1
u2.building = b1
eressea.settings.set("rules.owners.force_leave", "0")
process_orders()
assert_equal(b1, u1.building)
assert_equal(b1, u2.building)
end
function test_make_temp()
local r = region.create(0, 0, "plain")
local f1 = faction.create("owner@eressea.de", "human", "de")
local u1 = unit.create(f1, r, 10)
local u, u2
u1.building = building.create(r, "castle")
u1.status = 1
u1:clear_orders()
u1:add_order("MACHETEMP 1 Hodor")
u1:add_order("REKRUTIERE 1")
u1:add_order("ENDE")
process_orders()
for u in r.units do
if u~=u1 then
u2 = u
break
end
end
assert_not_equal(nil, u2)
assert_not_equal(nil, u2.building)
assert_equal(1, u2.number)
assert_equal(1, u2.status)
assert_equal("Hodor", u2.name)
end
function test_force_leave_postcombat()
local r = region.create(0, 0, "plain")
local f1 = faction.create("owner@eressea.de", "human", "de")
local f2 = faction.create("guest@eressea.de", "human", "de")
local u1 = unit.create(f1, r, 10)
local u2 = unit.create(f2, r, 10)
local u, u3
local b1 = building.create(r, "castle")
u1.building = b1
u2.building = b1
eressea.settings.set("rules.owners.force_leave", "1")
u1:clear_orders()
u1:add_order("ATTACKIERE " .. itoa36(u2.id))
u2:clear_orders()
u2:add_order("MACHETEMP 2 Hodor")
u2:add_order("REKRUTIERE 1")
u2:add_order("ENDE")
process_orders()
for u in r.units do
if u~=u1 and u~=u2 then
u3 = u
break
end
end
assert_not_equal(nil, u3)
assert_equal(nil, u3.building)
assert_equal(1, u3.number)
end

View File

@ -3946,7 +3946,6 @@ static bool start_battle(region * r, battle ** bp)
unit *u;
bool fighting = false;
/* list_foreach geht nicht, wegen flucht */
for (u = r->units; u != NULL; u = u->next) {
if (fval(u, UFL_LONGACTION))
continue;

View File

@ -20,6 +20,7 @@ without prior permission by the authors of Eressea.
#include <kernel/building.h>
#include <kernel/region.h>
#include <util/log.h>
#include <util/language.h>
#include <tolua.h>
@ -190,7 +191,13 @@ static int tolua_building_create(lua_State * L)
{
region *r = (region *)tolua_tousertype(L, 1, 0);
const char *bname = tolua_tostring(L, 2, 0);
if (bname) {
if (!r) {
log_error("building.create expects a region as argument 1");
}
if (!bname) {
log_error("building.create expects a name as argument 2");
}
if (bname) {
const building_type *btype = bt_find(bname);
if (btype) {
building *b = new_building(btype, r, default_locale);

View File

@ -991,7 +991,7 @@ void init_locale(struct locale *lang)
addtoken(tokens, name, var);
}
else {
log_error("no translation for magic school %s in locale %s", tok, locale_name(lang));
log_warning("no translation for magic school %s in locale %s", tok, locale_name(lang));
}
tok = strtok(NULL, " ");
}

View File

@ -183,6 +183,7 @@ race *rc_get_or_create(const char *zName)
rc->recruit_multi = 1.0F;
rc->regaura = 1.0F;
rc->speed = 1.0F;
rc->battle_flags = BF_CANATTACK;
if (strchr(zName, ' ') != NULL) {
log_error("race '%s' has an invalid name. remove spaces\n", zName);
assert(strchr(zName, ' ') == NULL);

View File

@ -1726,7 +1726,7 @@ static int parse_races(xmlDocPtr doc)
if (xml_bvalue(node, "resistpierce", false))
rc->battle_flags |= BF_RES_PIERCE;
if (xml_bvalue(node, "canattack", true))
rc->battle_flags |= BF_CANATTACK;
rc->battle_flags |= BF_CANATTACK; // TODO: invert this flag, so rc_get_or_create gets simpler
for (child = node->children; child; child = child->next) {
if (strcmp((const char *)child->name, "ai") == 0) {

View File

@ -3346,7 +3346,7 @@ void new_units(void)
}
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
if (name != NULL)
free(name);
free(name); // TODO: use a buffer on the stack instead?
fset(u2, UFL_ISNEW);
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
@ -4378,6 +4378,12 @@ void init_processor(void)
{
int p;
while (processors) {
processor * next = processors->next;
free(processors);
processors = next;
}
p = 10;
add_proc_global(p, new_units, "Neue Einheiten erschaffen");
@ -4528,13 +4534,9 @@ void init_processor(void)
void processorders(void)
{
static int init = 0;
init_processor();
if (!init) {
init_processor();
init = 1;
}
update_spells();
update_spells();
process();
/*************************************************/

View File

@ -114,8 +114,18 @@ const char *combatstatus[] = {
const char *report_kampfstatus(const unit * u, const struct locale *lang)
{
static char fsbuf[64]; // FIXME: static return value
const char * status = LOC(lang, combatstatus[u->status]);
strlcpy(fsbuf, LOC(lang, combatstatus[u->status]), sizeof(fsbuf));
if (!status) {
const char *lname = locale_name(lang);
struct locale *wloc = get_or_create_locale(lname);
log_error("no translation for combat status %s in %s", combatstatus[u->status], lname);
locale_setstring(wloc, combatstatus[u->status], combatstatus[u->status]);
strlcpy(fsbuf, combatstatus[u->status], sizeof(fsbuf));
}
else {
strlcpy(fsbuf, status, sizeof(fsbuf));
}
if (fval(u, UFL_NOAID)) {
strcat(fsbuf, ", ");
strcat(fsbuf, LOC(lang, "status_noaid"));

View File

@ -31,6 +31,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
register const char *s = src;
register size_t n = siz;
assert(src && dst);
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {