Merge pull request #315 from ennorehling/feature/tests-leaks

close some memory leaks in tests
This commit is contained in:
Enno Rehling 2015-10-15 08:57:18 +02:00
commit 43bf8a4ade
53 changed files with 479 additions and 201 deletions

View file

@ -185,11 +185,10 @@ static void test_building_defence_bonus(CuTest * tc)
building_type * btype;
faction * f;
int def;
test_cleanup();
test_create_world();
r = findregion(0, 0);
register_buildings();
btype = bt_get_or_create("castle");
r = test_create_region(0, 0, 0);
btype = test_create_buildingtype("castle");
btype->protection = (int(*)(struct building *, struct unit *, building_bonus))get_function("building_protection");
btype->construction->defense_bonus = 3;
bld = test_create_building(r, btype);

View file

@ -399,6 +399,7 @@ void free_recruitments(recruitment * recruits)
while (rec->requests) {
request *req = rec->requests;
rec->requests = req->next;
free_order(req->ord);
free(req);
}
free(rec);
@ -953,8 +954,9 @@ void economics(region * r)
}
}
if (recruitorders)
if (recruitorders) {
expandrecruit(r, recruitorders);
}
remove_empty_units_in_region(r);
for (u = r->units; u; u = u->next) {

View file

@ -28,9 +28,8 @@ static void test_give_control_building(CuTest * tc)
region *r;
test_cleanup();
test_create_world();
f = test_create_faction(0);
r = findregion(0, 0);
r = test_create_region(0, 0, 0);
b = test_create_building(r, 0);
u1 = test_create_unit(f, r);
u_set_building(u1, b);
@ -50,9 +49,8 @@ static void test_give_control_ship(CuTest * tc)
region *r;
test_cleanup();
test_create_world();
f = test_create_faction(0);
r = findregion(0, 0);
r = test_create_region(0, 0, 0);
sh = test_create_ship(r, 0);
u1 = test_create_unit(f, r);
u_set_ship(u1, sh);

View file

@ -13,8 +13,10 @@
#endif
#include <triggers/triggers.h>
#include <util/language.h>
#include <util/functions.h>
#include <kernel/xmlreader.h>
#include <kernel/item.h>
#include <kernel/curse.h>
#include <kernel/building.h>
#include <modules/gmcmd.h>
#include <modules/xmas.h>
@ -46,6 +48,8 @@ void game_done(void)
#endif
calendar_cleanup();
#endif
free_functions();
free_curses();
kernel_done();
}

View file

@ -152,6 +152,7 @@ static void test_give_men_in_ocean(CuTest * tc) {
msg = disband_men(1, env.src, NULL);
CuAssertStrEquals(tc, "give_person_ocean", (const char *)msg->parameters[0].v);
CuAssertIntEquals(tc, 0, env.src->number);
msg_release(msg);
test_cleanup();
}
@ -177,6 +178,7 @@ static void test_give_men_none(CuTest * tc) {
CuAssertStrEquals(tc, "error96", test_get_messagetype(msg));
CuAssertIntEquals(tc, 1, env.dst->number);
CuAssertIntEquals(tc, 1, env.src->number);
msg_release(msg);
test_cleanup();
}
@ -193,6 +195,7 @@ static void test_give_men_other_faction(CuTest * tc) {
CuAssertStrEquals(tc, "give_person", (const char *)msg->parameters[0].v);
CuAssertIntEquals(tc, 2, env.dst->number);
CuAssertIntEquals(tc, 0, env.src->number);
msg_release(msg);
test_cleanup();
}
@ -217,8 +220,9 @@ static void test_give_men_requires_contact(CuTest * tc) {
give_cmd(env.src, ord);
CuAssertPtrEquals(tc, 0, test_find_messagetype(env.f1->msgs, "give_person"));
CuAssertPtrNotNull(tc, test_find_messagetype(env.f1->msgs, "feedback_no_contact"));
free_order(ord);
msg_release(msg);
free_order(ord);
test_cleanup();
}
@ -231,6 +235,7 @@ static void test_give_men_not_to_self(CuTest * tc) {
msg = give_men(1, env.src, env.src, NULL);
CuAssertStrEquals(tc, "error10", test_get_messagetype(msg));
CuAssertIntEquals(tc, 1, env.src->number);
msg_release(msg);
test_cleanup();
}
@ -247,6 +252,7 @@ static void test_give_peasants(CuTest * tc) {
CuAssertStrEquals(tc, "give_person_peasants", (const char*)msg->parameters[0].v);
CuAssertIntEquals(tc, 0, env.src->number);
CuAssertIntEquals(tc, 1, env.r->land->peasants);
msg_release(msg);
test_cleanup();
}
@ -334,7 +340,7 @@ static void test_give_invalid_target(CuTest *tc) {
setup_give(&env);
i_change(&env.src->items, env.itype, 10);
lang = get_or_create_locale("test");
lang = get_or_create_locale("de");
env.f1->locale = lang;
locale_setstring(lang, "KRAEUTER", "KRAUT");
init_locale(lang);

View file

@ -627,19 +627,27 @@ message *msg_materials_required(unit * u, order * ord,
const construction * ctype, int multi)
{
int c;
message *msg;
/* something missing from the list of materials */
resource *reslist = NULL;
if (multi <= 0 || multi == INT_MAX)
multi = 1;
for (c = 0; ctype && ctype->materials[c].number; ++c) {
// TODO: lots of alloc/dealloc calls here (make var_copy_resources take an array)
resource *res = malloc(sizeof(resource));
res->number = multi * ctype->materials[c].number / ctype->reqsize;
res->type = ctype->materials[c].rtype;
res->next = reslist;
reslist = res;
}
return msg_feedback(u, ord, "build_required", "required", reslist);
msg = msg_feedback(u, ord, "build_required", "required", reslist);
while (reslist) {
resource *res = reslist->next;
free(reslist);
reslist = res;
}
return msg;
}
int maxbuild(const unit * u, const construction * cons)
@ -977,3 +985,12 @@ void continue_ship(unit * u, int want)
build_ship(u, sh, want);
}
void free_construction(struct construction *cons)
{
while (cons) {
construction *next = cons->improvement;
free(cons->materials);
free(cons);
cons = next;
}
}

View file

@ -65,6 +65,7 @@ extern "C" {
} construction;
void free_construction(struct construction *cons);
extern int destroy_cmd(struct unit *u, struct order *ord);
extern int leave_cmd(struct unit *u, struct order *ord);

View file

@ -45,6 +45,11 @@ static unit * setup_build(build_fixture *bf) {
return bf->u;
}
static void teardown_build(build_fixture *bf) {
free(bf->cons.materials);
test_cleanup();
}
static void test_build_requires_materials(CuTest *tc) {
build_fixture bf = { 0 };
unit *u;
@ -57,7 +62,7 @@ static void test_build_requires_materials(CuTest *tc) {
i_change(&u->items, itype, 2);
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
test_cleanup();
teardown_build(&bf);
}
static void test_build_requires_building(CuTest *tc) {
@ -79,7 +84,7 @@ static void test_build_requires_building(CuTest *tc) {
CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 1));
btype->maxcapacity = 0;
CuAssertIntEquals_Msg(tc, "cannot build when production building capacity exceeded", EBUILDINGREQ, build(u, &bf.cons, 0, 1));
test_cleanup();
teardown_build(&bf);
}
static void test_build_failure_missing_skill(CuTest *tc) {
@ -91,7 +96,7 @@ static void test_build_failure_missing_skill(CuTest *tc) {
rtype = bf.cons.materials[0].rtype;
i_change(&u->items, rtype->itype, 1);
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &bf.cons, 1, 1));
test_cleanup();
teardown_build(&bf);
}
static void test_build_failure_low_skill(CuTest *tc) {
@ -104,7 +109,7 @@ static void test_build_failure_low_skill(CuTest *tc) {
i_change(&u->items, rtype->itype, 1);
set_level(u, SK_ARMORER, bf.cons.minskill - 1);
CuAssertIntEquals(tc, ELOWSKILL, build(u, &bf.cons, 0, 10));
test_cleanup();
teardown_build(&bf);
}
static void test_build_failure_completed(CuTest *tc) {
@ -119,7 +124,7 @@ static void test_build_failure_completed(CuTest *tc) {
bf.cons.maxsize = 1;
CuAssertIntEquals(tc, ECOMPLETE, build(u, &bf.cons, bf.cons.maxsize, 10));
CuAssertIntEquals(tc, 1, i_get(u->items, rtype->itype));
test_cleanup();
teardown_build(&bf);
}
static void test_build_limits(CuTest *tc) {
@ -145,7 +150,7 @@ static void test_build_limits(CuTest *tc) {
i_change(&u->items, rtype->itype, 4);
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 10));
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
test_cleanup();
teardown_build(&bf);
}
static void test_build_with_ring(CuTest *tc) {
@ -164,7 +169,7 @@ static void test_build_with_ring(CuTest *tc) {
i_change(&u->items, ring, 1);
CuAssertIntEquals(tc, 10, build(u, &bf.cons, 0, 20));
CuAssertIntEquals(tc, 10, i_get(u->items, rtype->itype));
test_cleanup();
teardown_build(&bf);
}
static void test_build_with_potion(CuTest *tc) {
@ -192,7 +197,7 @@ static void test_build_with_potion(CuTest *tc) {
CuAssertIntEquals(tc, 4, get_effect(u, ptype));
CuAssertIntEquals(tc, 4, build(u, &bf.cons, 0, 20));
CuAssertIntEquals(tc, 2, get_effect(u, ptype));
test_cleanup();
teardown_build(&bf);
}
static void test_build_building_no_materials(CuTest *tc) {
@ -208,7 +213,7 @@ static void test_build_building_no_materials(CuTest *tc) {
CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, u->orders));
CuAssertPtrEquals(tc, 0, u->region->buildings);
CuAssertPtrEquals(tc, 0, u->building);
test_cleanup();
teardown_build(&bf);
}
static void test_build_building_with_golem(CuTest *tc) {
@ -228,7 +233,7 @@ static void test_build_building_with_golem(CuTest *tc) {
CuAssertPtrNotNull(tc, u->region->buildings);
CuAssertIntEquals(tc, 1, u->region->buildings->size);
CuAssertIntEquals(tc, 0, u->number);
test_cleanup();
teardown_build(&bf);
}
static void test_build_building_success(CuTest *tc) {
@ -253,7 +258,7 @@ static void test_build_building_success(CuTest *tc) {
CuAssertPtrEquals(tc, u->region->buildings, u->building);
CuAssertIntEquals(tc, 1, u->building->size);
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
test_cleanup();
teardown_build(&bf);
}
CuSuite *get_build_suite(void)

View file

@ -94,6 +94,8 @@ void bt_register(building_type * type)
void free_buildingtype(void *ptr) {
building_type *btype = (building_type *)ptr;
free_construction(btype->construction);
free(btype->maintenance);
free(btype->_name);
free(btype);
}

View file

@ -1144,6 +1144,7 @@ void set_param(struct param **p, const char *key, const char *data)
}
else {
*p = par->next;
free(par->name);
free(par);
}
return;
@ -1596,10 +1597,6 @@ void kernel_init(void)
{
register_reports();
mt_clear();
if (!mt_find("missing_message")) {
mt_register(mt_new_va("missing_message", "name:string", 0));
mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0));
}
attrib_init();
translation_init();
}
@ -1611,6 +1608,8 @@ void set_default_order(int kwd) {
default_keyword = (keyword_t)kwd;
}
// TODO: outside of tests, default_keyword is never used, why is this here?
// see also test_long_order_hungry
order *default_order(const struct locale *lang)
{
static int usedefault = 1;

View file

@ -132,6 +132,8 @@ static void test_get_set_param(CuTest * tc)
CuAssertStrEquals(tc, "foo", get_param(par, "bar"));
set_param(&par, "bar", NULL);
CuAssertPtrEquals(tc, NULL, (void *)get_param(par, "bar"));
free_params(&par);
test_cleanup();
}
static void test_param_int(CuTest * tc)
@ -143,6 +145,8 @@ static void test_param_int(CuTest * tc)
set_param(&par, "bar", "42");
CuAssertIntEquals(tc, 23, get_param_int(par, "foo", 0));
CuAssertIntEquals(tc, 42, get_param_int(par, "bar", 0));
free_params(&par);
test_cleanup();
}
static void test_param_flt(CuTest * tc)
@ -154,6 +158,8 @@ static void test_param_flt(CuTest * tc)
set_param(&par, "bar", "42.0");
CuAssertDblEquals(tc, 23.0, get_param_flt(par, "foo", 0.0), 0.01);
CuAssertDblEquals(tc, 42.0, get_param_flt(par, "bar", 0.0), 0.01);
free_params(&par);
test_cleanup();
}
static void test_forbiddenid(CuTest *tc) {

View file

@ -293,11 +293,12 @@ attrib_type at_curse = {
#include <util/umlaut.h>
#include <quicklist.h>
static quicklist *cursetypes[256];
#define MAXCTHASH 128
static quicklist *cursetypes[MAXCTHASH];
void ct_register(const curse_type * ct)
{
unsigned int hash = tolower(ct->cname[0]);
unsigned int hash = tolower(ct->cname[0]) & 0xFF;
quicklist **ctlp = cursetypes + hash;
ql_set_insert(ctlp, (void *)ct);
@ -333,7 +334,7 @@ void ct_checknames(void) {
int i, qi;
quicklist *ctl;
for (i = 0; i < 256; ++i) {
for (i = 0; i < MAXCTHASH; ++i) {
ctl = cursetypes[i];
for (qi = 0; ctl; ql_advance(&ctl, &qi, 1)) {
curse_type *type = (curse_type *)ql_get(ctl, qi);
@ -818,3 +819,10 @@ double destr_curse(curse * c, int cast_level, double force)
}
return force;
}
void free_curses(void) {
int i;
for (i = 0; i != MAXCTHASH; ++i) {
ql_free(cursetypes[i]);
}
}

View file

@ -214,6 +214,8 @@ extern "C" {
int duration; /* Dauer der Verzauberung. Wird jede Runde vermindert */
} curse;
void free_curses(void); /* de-register all curse-types */
extern struct attrib_type at_curse;
void curse_write(const struct attrib *a, const void *owner,
struct storage *store);

View file

@ -33,9 +33,10 @@ static void test_curse(CuTest * tc)
cid = c->no;
result = findcurse(cid);
CuAssertPtrEquals(tc, c, result);
destroy_curse(c);
a_remove(&attrs, attrs);
result = findcurse(cid);
CuAssertPtrEquals(tc, NULL, result);
test_cleanup();
}
typedef struct {
@ -156,6 +157,6 @@ CuSuite *get_curse_suite(void)
SUITE_ADD_TEST(suite, test_good_dreams);
SUITE_ADD_TEST(suite, test_bad_dreams);
SUITE_ADD_TEST(suite, test_memstream);
DISABLE_TEST(suite, test_write_flag);
SUITE_ADD_TEST(suite, test_write_flag);
return suite;
}

View file

@ -69,16 +69,24 @@ faction *factions;
void free_faction(faction * f)
{
funhash(f);
if (f->msgs)
free_messagelist(f->msgs);
if (f->msgs) {
free_messagelist(f->msgs->begin);
free(f->msgs);
}
while (f->battles) {
struct bmsg *bm = f->battles;
f->battles = bm->next;
if (bm->msgs)
free_messagelist(bm->msgs);
if (bm->msgs) {
free_messagelist(bm->msgs->begin);
free(bm->msgs);
}
free(bm);
}
if (f->spellbook) {
free_spellbook(f->spellbook);
}
while (f->groups) {
group *g = f->groups;
f->groups = g->next;
@ -90,6 +98,10 @@ void free_faction(faction * f)
free(f->banner);
free(f->passw);
free(f->name);
if (f->seen_factions) {
ql_free(f->seen_factions);
f->seen_factions = 0;
}
while (f->attribs) {
a_remove(&f->attribs, f->attribs);

View file

@ -1178,12 +1178,17 @@ static item *default_spoil(const struct race *rc, int size)
return itm;
}
int free_itype(item_type *itype) {
static void free_itype(item_type *itype) {
free(itype->construction);
free(itype->_appearance[0]);
free(itype->_appearance[1]);
free(itype);
return 0;
}
static void free_wtype(weapon_type *wtype) {
free(wtype->damage[0]);
free(wtype->damage[1]);
free(wtype);
}
int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
@ -1193,6 +1198,9 @@ int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbd
if (rtype->itype) {
free_itype(rtype->itype);
}
if (rtype->wtype) {
free_wtype(rtype->wtype);
}
free(rtype);
return 0;
}

View file

@ -211,7 +211,7 @@ extern "C" {
typedef struct weapon_type {
const item_type *itype;
const char *damage[2];
char *damage[2];
unsigned int flags;
skill_t skill;
int minskill;

View file

@ -270,6 +270,7 @@ static void json_terrain(cJSON *json, terrain_type *ter) {
int size = cJSON_GetArraySize(child);
if (size > 0) {
int n;
free(ter->herbs);
ter->herbs = malloc(sizeof(const item_type *) * (size + 1));
ter->herbs[size] = 0;
for (n = 0, entry = child->child; entry; entry = entry->next) {

View file

@ -31,6 +31,7 @@ static const struct race * race_with_flag(const char * name) {
json = cJSON_Parse(data);
free_races();
json_config(json);
cJSON_Delete(json);
return rc_find("orc");
}
@ -78,6 +79,7 @@ static void test_settings(CuTest * tc)
CuAssertStrEquals(tc, "1d4", get_param(global.parameters, "string"));
CuAssertIntEquals(tc, 14, get_param_int(global.parameters, "integer", 0));
CuAssertDblEquals(tc, 1.5f, get_param_flt(global.parameters, "float", 0), 0.01);
cJSON_Delete(json);
test_cleanup();
}
@ -96,6 +98,7 @@ static void test_prefixes(CuTest * tc)
CuAssertStrEquals(tc, "snow", race_prefixes[0]);
CuAssertStrEquals(tc, "dark", race_prefixes[2]);
CuAssertPtrEquals(tc, 0, race_prefixes[3]);
cJSON_Delete(json);
test_cleanup();
}
@ -121,6 +124,7 @@ static void test_disable(CuTest * tc)
CuAssertTrue(tc, keyword_disabled(K_PAY));
CuAssertTrue(tc, keyword_disabled(K_BESIEGE));
CuAssertIntEquals(tc, 0, get_param_int(global.parameters, "module.enabled", 1));
cJSON_Delete(json);
test_cleanup();
}
@ -164,6 +168,7 @@ static void test_races(CuTest * tc)
CuAssertIntEquals(tc, 4, rc->capacity);
CuAssertIntEquals(tc, 5, rc->hitpoints);
CuAssertIntEquals(tc, 6, rc->armor);
cJSON_Delete(json);
test_cleanup();
}
@ -183,6 +188,7 @@ static void test_findrace(CuTest *tc) {
rc = findrace("Zwerg", lang);
CuAssertPtrNotNull(tc, rc);
CuAssertStrEquals(tc, "dwarf", rc->_name);
cJSON_Delete(json);
test_cleanup();
}
@ -216,6 +222,8 @@ static void test_items(CuTest * tc)
CuAssertPtrNotNull(tc, rt_find("axe"));
CuAssertPtrNotNull(tc, (void *)get_resourcetype(R_HORSE));
cJSON_Delete(json);
test_cleanup();
}
static void test_ships(CuTest * tc)
@ -254,6 +262,7 @@ static void test_ships(CuTest * tc)
CuAssertPtrEquals(tc, (void *)ter, (void *)st->coasts[0]);
CuAssertPtrEquals(tc, 0, (void *)st->coasts[1]);
cJSON_Delete(json);
test_cleanup();
}
@ -281,6 +290,8 @@ static void test_castles(CuTest *tc) {
CuAssertPtrNotNull(tc, bt->construction->improvement);
CuAssertIntEquals(tc, 6, bt->construction->improvement->maxsize);
CuAssertPtrEquals(tc, 0, bt->construction->improvement->improvement);
cJSON_Delete(json);
test_cleanup();
}
static void test_spells(CuTest * tc)
@ -299,6 +310,7 @@ static void test_spells(CuTest * tc)
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, "u+", sp->syntax);
cJSON_Delete(json);
test_cleanup();
CuAssertPtrEquals(tc, 0, find_spell("fireball"));
}
@ -364,6 +376,7 @@ static void test_buildings(CuTest * tc)
CuAssertIntEquals(tc, 20, bt->construction->maxsize);
CuAssertIntEquals(tc, 1, bt->construction->minskill);
CuAssertPtrEquals(tc, 0, bt->construction->improvement);
cJSON_Delete(json);
test_cleanup();
}
@ -388,6 +401,7 @@ static void test_buildings_default(CuTest * tc)
CuAssertPtrEquals(tc, (void *)bt, (void *)bt_find("house"));
CuAssertIntEquals(tc, 0, memcmp(bt, &clone, sizeof(building_type)));
cJSON_Delete(json);
test_cleanup();
}
@ -412,6 +426,7 @@ static void test_ships_default(CuTest * tc)
CuAssertPtrEquals(tc, (void *)st, (void *)st_find("hodor"));
CuAssertIntEquals(tc, 0, memcmp(st, &clone, sizeof(ship_type)));
cJSON_Delete(json);
test_cleanup();
}
@ -431,6 +446,7 @@ static void test_configs(CuTest * tc)
json_config(json);
CuAssertPtrNotNull(tc, buildingtypes);
unlink("test.json");
cJSON_Delete(json);
test_cleanup();
}
@ -472,6 +488,7 @@ static void test_terrains(CuTest * tc)
CuAssertPtrEquals(tc, rt_get_or_create("iron"), (resource_type *)ter->production[1].type);
CuAssertPtrEquals(tc, 0, (void *)ter->production[2].type);
cJSON_Delete(json);
test_cleanup();
}
@ -493,6 +510,7 @@ static void test_directions(CuTest * tc)
CuAssertIntEquals(tc, D_NORTHWEST, get_direction("nordwest", lang));
CuAssertIntEquals(tc, D_PAUSE, get_direction("pause", lang));
cJSON_Delete(json);
test_cleanup();
}
@ -517,6 +535,7 @@ static void test_skills(CuTest * tc)
CuAssertStrEquals(tc, "ALCHEMIE", LOC(lang, "skill::alchemy"));
CuAssertStrEquals(tc, "ARMBRUST", LOC(lang, "skill::crossbow"));
cJSON_Delete(json);
test_cleanup();
}
@ -540,6 +559,7 @@ static void test_keywords(CuTest * tc)
CuAssertStrEquals(tc, "LERNEN", LOC(lang, "keyword::study"));
CuAssertStrEquals(tc, "NACH", LOC(lang, "keyword::move"));
cJSON_Delete(json);
test_cleanup();
}
@ -558,6 +578,8 @@ static void test_strings(CuTest * tc)
json_config(json);
CuAssertStrEquals(tc, "NACH", LOC(lang, "move"));
CuAssertStrEquals(tc, "LERNEN", LOC(lang, "study"));
cJSON_Delete(json);
test_cleanup();
}
static void test_infinitive_from_config(CuTest *tc) {
@ -578,6 +600,7 @@ static void test_infinitive_from_config(CuTest *tc) {
ord = create_order(K_STUDY, lang, "");
CuAssertStrEquals(tc, "LERNE", get_command(ord, buffer, sizeof(buffer)));
free_order(ord);
cJSON_Delete(json);
test_cleanup();
}

View file

@ -91,6 +91,9 @@ struct message *msg_feedback(const struct unit *u, struct order *ord,
if (!mtype) {
log_error("trying to create message of unknown type \"%s\"\n", name);
if (!mt_find("missing_feedback")) {
mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0));
}
return msg_message("missing_feedback", "unit region command name", u,
u->region, ord, name);
}
@ -154,6 +157,9 @@ message *msg_message(const char *name, const char *sig, ...)
if (!mtype) {
log_warning("trying to create message of unknown type \"%s\"\n", name);
if (strcmp(name, "missing_message") != 0) {
if (!mt_find("missing_message")) {
mt_register(mt_new_va("missing_message", "name:string", 0));
}
return msg_message("missing_message", "name", name);
}
return NULL;
@ -283,17 +289,14 @@ void syntax_error(const struct unit *u, struct order *ord)
extern unsigned int new_hashstring(const char *s);
void free_messagelist(message_list * msgs)
void free_messagelist(mlist *msgs)
{
struct mlist **mlistptr;
if (msgs) {
for (mlistptr = &msgs->begin; *mlistptr;) {
struct mlist *ml = *mlistptr;
*mlistptr = ml->next;
msg_release(ml->msg);
free(ml);
}
free(msgs);
for (mlistptr = &msgs; *mlistptr;) {
struct mlist *ml = *mlistptr;
*mlistptr = ml->next;
msg_release(ml->msg);
free(ml);
}
}

View file

@ -37,7 +37,7 @@ extern "C" {
struct mlist *begin, **end;
} message_list;
void free_messagelist(message_list * msgs);
void free_messagelist(struct mlist *msgs);
typedef struct msglevel {
/* used to set specialized msg-levels */

View file

@ -39,13 +39,16 @@ void test_message(CuTest *tc) {
static void test_merge_split(CuTest *tc) {
message_list *mlist = 0, *append = 0;
struct mlist **split;
struct mlist **split; // TODO: why is this a double asterisk?
message_type *mtype = mt_new("custom", NULL);
message *msg;
test_cleanup();
mt_register(mtype);
add_message(&mlist, msg_message(mtype->name, ""));
add_message(&append, msg_message(mtype->name, ""));
add_message(&mlist, msg = msg_message(mtype->name, ""));
msg_release(msg);
add_message(&append, msg = msg_message(mtype->name, ""));
msg_release(msg);
CuAssertPtrEquals(tc, 0, mlist->begin->next);
CuAssertPtrEquals(tc, &mlist->begin->next, mlist->end);
@ -57,6 +60,11 @@ static void test_merge_split(CuTest *tc) {
CuAssertPtrEquals(tc, append->begin, mlist->begin->next);
split_messages(mlist, split);
CuAssertPtrEquals(tc, 0, mlist->begin->next);
free_messagelist(*split);
free_messagelist(mlist->begin);
free(mlist);
free_messagelist(append->begin);
free(append);
test_cleanup();
}

View file

@ -245,6 +245,7 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
if (data == NULL) {
mkdata(&data, 0, kwd, lindex, 0);
data->_refcount = 1;
locale_array[lindex]->short_orders[kwd] = data;
}
++data->_refcount;
return data;
@ -254,7 +255,7 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
return data;
}
static void free_localedata(int lindex) {
static void clear_localedata(int lindex) {
int i;
for (i = 0; i != MAXKEYWORDS; ++i) {
release_data(locale_array[lindex]->short_orders[i]);
@ -267,6 +268,17 @@ static void free_localedata(int lindex) {
locale_array[lindex]->lang = 0;
}
void close_orders(void) {
int i;
for (i = 0; i != MAXLOCALES; ++i) {
if (locale_array[i]){
clear_localedata(i);
free(locale_array[i]);
locale_array[i] = 0;
}
}
}
static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
const struct locale *lang)
{
@ -295,7 +307,7 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data));
}
else if (locale_array[lindex]->lang != lang) {
free_localedata(lindex);
clear_localedata(lindex);
}
locale_array[lindex]->lang = lang;

View file

@ -61,6 +61,8 @@ extern "C" {
char *write_order(const order * ord, char *buffer, size_t size);
keyword_t init_order(const struct order *ord);
void close_orders(void);
#ifdef __cplusplus
}
#endif

View file

@ -99,8 +99,11 @@ static void test_parse_make_temp(CuTest *tc) {
static void test_parse_maketemp(CuTest *tc) {
char cmd[32];
order *ord;
struct locale * lang = get_or_create_locale("en");
struct locale * lang;
test_cleanup();
lang = get_or_create_locale("en");
locale_setstring(lang, keyword(K_MAKE), "MAKE");
locale_setstring(lang, keyword(K_MAKETEMP), "MAKETEMP");
locale_setstring(lang, "TEMP", "TEMP");
@ -113,17 +116,22 @@ static void test_parse_maketemp(CuTest *tc) {
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
CuAssertStrEquals(tc, "herp", getstrtoken());
free_order(ord);
test_cleanup();
}
static void test_init_order(CuTest *tc) {
order *ord;
struct locale * lang = get_or_create_locale("en");
struct locale * lang;
test_cleanup();
lang = get_or_create_locale("en");
ord = create_order(K_MAKETEMP, lang, "hurr durr");
CuAssertIntEquals(tc, K_MAKETEMP, init_order(ord));
CuAssertStrEquals(tc, "hurr", getstrtoken());
CuAssertStrEquals(tc, "durr", getstrtoken());
free_order(ord);
test_cleanup();
}
static void test_getstrtoken(CuTest *tc) {
@ -146,8 +154,10 @@ static void test_skip_token(CuTest *tc) {
static void test_replace_order(CuTest *tc) {
order *orders = 0, *orig, *repl;
struct locale * lang = get_or_create_locale("en");
struct locale * lang;
test_cleanup();
lang = get_or_create_locale("en");
orig = create_order(K_MAKE, lang, 0);
repl = create_order(K_ALLY, lang, 0);
replace_order(&orders, orig, repl);
@ -157,6 +167,9 @@ static void test_replace_order(CuTest *tc) {
CuAssertPtrNotNull(tc, orders);
CuAssertPtrEquals(tc, 0, orders->next);
CuAssertIntEquals(tc, getkeyword(repl), getkeyword(orders));
free_order(orders);
free_order(repl);
test_cleanup();
}
CuSuite *get_order_suite(void)

View file

@ -178,6 +178,7 @@ void test_change_resource(CuTest * tc)
CuAssertIntEquals(tc, have + 1, change_resource(u, rtype, 1));
CuAssertIntEquals(tc, have + 1, get_resource(u, rtype));
}
test_cleanup();
}
CuSuite *get_pool_suite(void)

View file

@ -753,6 +753,7 @@ void remove_region(region ** rlist, region * r)
static void freeland(land_region * lr)
{
free(lr->ownership);
while (lr->demands) {
struct demand *d = lr->demands;
lr->demands = d->next;
@ -819,15 +820,18 @@ void free_region(region * r)
freeland(r->land);
if (r->msgs) {
free_messagelist(r->msgs);
free_messagelist(r->msgs->begin);
free(r->msgs);
r->msgs = 0;
}
while (r->individual_messages) {
struct individual_message *msg = r->individual_messages;
r->individual_messages = msg->next;
if (msg->msgs)
free_messagelist(msg->msgs);
if (msg->msgs) {
free_messagelist(msg->msgs->begin);
free(msg->msgs);
}
free(msg);
}

View file

@ -245,6 +245,7 @@ static void free_shiptype(void *ptr) {
ship_type *stype = (ship_type *)ptr;
free(stype->_name);
free(stype->coasts);
free_construction(stype->construction);
free(stype);
}

View file

@ -36,8 +36,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
static critbit_tree cb_spells;
quicklist * spells;
static void free_spell_cb(void *cbdata) {
spell *sp = (spell *)cbdata;
free(sp->syntax);
free(sp->parameter);
free(sp->sname);
free(sp->components);
free(sp);
}
void free_spells(void) {
cb_clear(&cb_spells);
ql_foreach(spells, free_spell_cb);
ql_free(spells);
spells = 0;
}

View file

@ -50,11 +50,11 @@ extern "C" {
void showspells(struct region *r, struct unit *u);
int sp_antimagiczone(struct castorder *co);
extern struct spell * create_spell(const char * name, unsigned int id);
extern struct spell * find_spell(const char *name);
extern struct spell * find_spellbyid(unsigned int i);
extern void add_spell(struct quicklist **slistp, spell * sp);
extern void free_spells(void);
struct spell * create_spell(const char * name, unsigned int id);
struct spell * find_spell(const char *name);
struct spell * find_spellbyid(unsigned int i);
void add_spell(struct quicklist **slistp, spell * sp);
void free_spells(void);
/** globals **/
extern struct attrib_type at_unitdissolve;

View file

@ -63,6 +63,7 @@ void free_terrains(void)
terrain_type * t = registered_terrains;
registered_terrains = t->next;
free(t->_name);
free(t->herbs);
if (t->production) {
for (n = 0; t->production[n].type; ++n) {
free(t->production[n].base);

View file

@ -64,7 +64,7 @@ extern "C" {
short max_road; /* this many stones make a full road */
short distribution; /* multiplier used for seeding */
struct terrain_production *production;
const struct item_type **herbs; /* zero-terminated array of herbs */
struct item_type **herbs; /* zero-terminated array of herbs */
const char *(*name) (const struct region * r);
struct terrain_type *next;
} terrain_type;

View file

@ -724,30 +724,24 @@ static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
}
static void test_peasant_luck_effect(CuTest *tc) {
const char *plf = get_param(global.parameters, "rules.peasants.peasantluck.factor");
const char *gf = get_param(global.parameters, "rules.peasants.growth.factor");
test_cleanup();
set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10");
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
statistic_test(tc, 100, 0, 1000, 0, 0, 0);
statistic_test(tc, 100, 2, 1000, 0, 1, 1);
/*
statistic_test(tc, 1000, 400, 1000, 0, (int)(400 * 10 * 0.001 * .75),
(int)(400 * 10 * 0.001 * .75));
*/
statistic_test(tc, 1000, 400, 1000, 0, 3, 3);
statistic_test(tc, 1000, 1000, 2000, .5, 1, 501);
set_param(&global.parameters, "rules.peasants.growth.factor", "1");
statistic_test(tc, 1000, 1000, 1000, 0, 501, 501);
set_param(&global.parameters, "rules.peasants.peasantluck.factor", plf);
set_param(&global.parameters, "rules.peasants.growth.factor", gf);
test_cleanup();
}
static void test_luck_message(CuTest *tc) {
region* r;
test_cleanup();
r = test_create_region(0, 0, NULL);
rsetpeasants(r, 1);
@ -1005,7 +999,8 @@ static void test_long_order_buy_cast(CuTest *tc) {
}
static void test_long_order_hungry(CuTest *tc) {
// TODO: write more tests
// FIXME: set_default_order is a test-only function, this is a bad test.
// see also default_order
unit *u;
test_cleanup();
set_param(&global.parameters, "hunger.long", "1");

View file

@ -2984,11 +2984,15 @@ spellbook * get_spellbook(const char * name)
return result;
}
int free_spellbook_cb(const void *match, const void *key, size_t keylen, void *data) {
spellbook *sb;
cb_get_kv(match, &sb, sizeof(sb));
void free_spellbook(spellbook *sb) {
spellbook_clear(sb);
free(sb);
}
static int free_spellbook_cb(const void *match, const void *key, size_t keylen, void *data) {
spellbook *sb;
cb_get_kv(match, &sb, sizeof(sb));
free_spellbook(sb);
return 0;
}

View file

@ -363,6 +363,7 @@ extern "C" {
struct spellbook * get_spellbook(const char * name);
void free_spellbooks(void);
void free_spellbook(struct spellbook *sb);
#ifdef __cplusplus
}
#endif

View file

@ -40,6 +40,7 @@ void test_updatespells(CuTest * tc)
CuAssertPtrNotNull(tc, f->spellbook);
CuAssertIntEquals(tc, 1, ql_length(f->spellbook->spells));
CuAssertPtrNotNull(tc, spellbook_get(f->spellbook, sp));
free_spellbook(book);
test_cleanup();
}

View file

@ -269,6 +269,7 @@ static void test_ship_trails(CuTest *tc) {
CuAssertPtrEquals(tc, 0, a_find(r1->attribs, &at_shiptrail));
CuAssertPtrNotNull(tc, a_find(r2->attribs, &at_shiptrail));
CuAssertPtrNotNull(tc, a_find(r3->attribs, &at_shiptrail));
free_regionlist(route);
test_cleanup();
}
@ -290,6 +291,7 @@ static void test_age_trails(CuTest *tc) {
CuAssertPtrNotNull(tc, r1->attribs);
a_age(&r1->attribs);
CuAssertPtrEquals(tc, 0, r1->attribs);
free_regionlist(route);
test_cleanup();
}

View file

@ -18,7 +18,6 @@
static void setup_piracy(void) {
struct locale *lang;
terrain_type *t_ocean;
ship_type *st_boat;
test_cleanup();
@ -26,7 +25,7 @@ static void setup_piracy(void) {
lang = get_or_create_locale("de");
locale_setstring(lang, directions[D_EAST], "OSTEN");
init_directions(lang);
t_ocean = test_create_terrain("ocean", SAIL_INTO | SEA_REGION);
test_create_terrain("ocean", SAIL_INTO | SEA_REGION);
st_boat = test_create_shiptype("boat");
st_boat->cargo = 1000;
}

View file

@ -1733,6 +1733,23 @@ static variant var_copy_items(variant x)
return x;
}
static variant var_copy_resources(variant x)
{
resource *rsrc;
resource *rdst = NULL, **rptr = &rdst;
for (rsrc = (resource *)x.v; rsrc != NULL; rsrc = rsrc->next) {
resource *res = malloc(sizeof(resource));
res->number = rsrc->number;
res->type = rsrc->type;
*rptr = res;
rptr = &res->next;
}
*rptr = NULL;
x.v = rdst;
return x;
}
static void var_free_resources(variant x)
{
resource *rsrc = (resource *)x.v;
@ -2295,7 +2312,7 @@ void register_reports(void)
register_argtype("int", NULL, NULL, VAR_INT);
register_argtype("string", var_free_string, var_copy_string, VAR_VOIDPTR);
register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR);
register_argtype("resources", var_free_resources, NULL, VAR_VOIDPTR);
register_argtype("resources", var_free_resources, var_copy_resources, VAR_VOIDPTR);
register_argtype("items", var_free_resources, var_copy_items, VAR_VOIDPTR);
register_argtype("regions", var_free_regions, NULL, VAR_VOIDPTR);

View file

@ -66,6 +66,7 @@ static void test_reorder_units(CuTest * tc)
CuAssertPtrEquals(tc, u1, u2->next);
CuAssertPtrEquals(tc, u0, u1->next);
CuAssertPtrEquals(tc, 0, u0->next);
test_cleanup();
}
static void test_regionid(CuTest * tc) {
@ -88,11 +89,15 @@ static void test_regionid(CuTest * tc) {
CuAssertIntEquals(tc, 10, (int)len);
CuAssertStrEquals(tc, "plain (0,0", buffer);
CuAssertIntEquals(tc, 0x7d, buffer[11]);
test_cleanup();
}
static void test_seen_faction(CuTest *tc) {
faction *f1, *f2;
race *rc = test_create_race("human");
race *rc;
test_cleanup();
rc = test_create_race("human");
f1 = test_create_faction(rc);
f2 = test_create_faction(rc);
add_seen_faction(f1, f2);
@ -105,6 +110,7 @@ static void test_seen_faction(CuTest *tc) {
f2 = (faction *)ql_get(f1->seen_factions, 1);
f1 = (faction *)ql_get(f1->seen_factions, 0);
CuAssertTrue(tc, f1->no < f2->no);
test_cleanup();
}
static void test_write_spaces(CuTest *tc) {
@ -139,18 +145,25 @@ static void test_write_many_spaces(CuTest *tc) {
static void test_sparagraph(CuTest *tc) {
strlist *sp = 0;
split_paragraph(&sp, "Hello World", 0, 16, 0);
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, "Hello World", sp->s);
CuAssertPtrEquals(tc, 0, sp->next);
freestrlist(sp);
split_paragraph(&sp, "Hello World", 4, 16, 0);
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, " Hello World", sp->s);
CuAssertPtrEquals(tc, 0, sp->next);
freestrlist(sp);
split_paragraph(&sp, "Hello World", 4, 16, '*');
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, " * Hello World", sp->s);
CuAssertPtrEquals(tc, 0, sp->next);
freestrlist(sp);
split_paragraph(&sp, "12345678 90 12345678", 0, 8, '*');
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, "12345678", sp->s);
@ -159,6 +172,7 @@ static void test_sparagraph(CuTest *tc) {
CuAssertPtrNotNull(tc, sp->next->next);
CuAssertStrEquals(tc, "12345678", sp->next->next->s);
CuAssertPtrEquals(tc, 0, sp->next->next->next);
freestrlist(sp);
}
static void test_cr_unit(CuTest *tc) {

View file

@ -108,6 +108,7 @@ static void test_seen_travelthru(CuTest *tc) {
sr = find_seen(f->seen, r);
CuAssertPtrEquals(tc, r, sr->r);
CuAssertIntEquals(tc, see_travel, sr->mode);
seen_done(f->seen);
test_cleanup();
}
@ -141,6 +142,7 @@ static void test_seen_interval_backward(CuTest *tc) {
get_seen_interval(seen, &first, &last);
CuAssertPtrEquals(tc, regions, first);
CuAssertPtrEquals(tc, 0, last);
seen_done(seen);
test_cleanup();
}
@ -159,6 +161,7 @@ static void test_seen_interval_forward(CuTest *tc) {
get_seen_interval(seen, &first, &last);
CuAssertPtrEquals(tc, regions, first);
CuAssertPtrEquals(tc, 0, last);
seen_done(seen);
test_cleanup();
}

View file

@ -20,10 +20,13 @@
#include <assert.h>
static void test_create_castorder(castorder *order, unit *u, int level, float force, int range) {
static void test_create_castorder(castorder *co, unit *u, int level, float force, int range) {
struct locale * lang;
order *ord;
lang = get_or_create_locale("en");
create_castorder(order, u, NULL, NULL, u->region, level, force, range, create_order(K_CAST, lang, ""), NULL);
create_castorder(co, u, NULL, NULL, u->region, level, force, range, ord = create_order(K_CAST, lang, ""), NULL);
free_order(ord);
}
static void test_good_dreams(CuTest *tc) {
@ -31,7 +34,7 @@ static void test_good_dreams(CuTest *tc) {
struct faction *f1, *f2;
unit *u1, *u2;
int level;
castorder order;
castorder co;
test_cleanup();
test_create_world();
@ -41,9 +44,9 @@ static void test_good_dreams(CuTest *tc) {
u1 = test_create_unit(f1, r);
u2 = test_create_unit(f2, r);
test_create_castorder(&order, u1, 10, 10., 0);
test_create_castorder(&co, u1, 10, 10., 0);
level = sp_gooddreams(&order);
level = sp_gooddreams(&co);
CuAssertIntEquals(tc, 10, level);
curse *curse = get_curse(r->attribs, ct_find("gbdream"));
CuAssertTrue(tc, curse && curse->duration > 1);
@ -52,13 +55,15 @@ static void test_good_dreams(CuTest *tc) {
a_age(&r->attribs);
CuAssertIntEquals_Msg(tc, "good dreams give +1 to allies", 1, get_modifier(u1, SK_MELEE, 11, r, false));
CuAssertIntEquals_Msg(tc, "good dreams have no effect on non-allies", 0, get_modifier(u2, SK_MELEE, 11, r, false));
free_castorder(&co);
test_cleanup();
}
static void test_dreams(CuTest *tc) {
struct region *r;
struct faction *f1, *f2;
unit *u1, *u2;
castorder order;
castorder co;
test_cleanup();
test_create_world();
@ -68,15 +73,15 @@ static void test_dreams(CuTest *tc) {
u1 = test_create_unit(f1, r);
u2 = test_create_unit(f2, r);
test_create_castorder(&order, u1, 10, 10., 0);
test_create_castorder(&co, u1, 10, 10., 0);
sp_gooddreams(&order);
sp_baddreams(&order);
sp_gooddreams(&co);
sp_baddreams(&co);
a_age(&r->attribs);
CuAssertIntEquals_Msg(tc, "good dreams in same region as bad dreams", 1, get_modifier(u1, SK_MELEE, 11, r, false));
CuAssertIntEquals_Msg(tc, "bad dreams in same region as good dreams", -1, get_modifier(u2, SK_MELEE, 11, r, false));
free_castorder(&order);
free_castorder(&co);
test_cleanup();
}
@ -85,7 +90,7 @@ static void test_bad_dreams(CuTest *tc) {
struct faction *f1, *f2;
unit *u1, *u2;
int level;
castorder order;
castorder co;
test_cleanup();
test_create_world();
@ -95,9 +100,9 @@ static void test_bad_dreams(CuTest *tc) {
u1 = test_create_unit(f1, r);
u2 = test_create_unit(f2, r);
test_create_castorder(&order, u1, 10, 10., 0);
test_create_castorder(&co, u1, 10, 10., 0);
level = sp_baddreams(&order);
level = sp_baddreams(&co);
CuAssertIntEquals(tc, 10, level);
curse *curse = get_curse(r->attribs, ct_find("gbdream"));
CuAssertTrue(tc, curse && curse->duration > 1);
@ -107,7 +112,7 @@ static void test_bad_dreams(CuTest *tc) {
CuAssertIntEquals_Msg(tc, "bad dreams have no effect on allies", 0, get_modifier(u1, SK_MELEE, 11, r, false));
CuAssertIntEquals_Msg(tc, "bad dreams give -1 to non-allies", -1, get_modifier(u2, SK_MELEE, 11, r, false));
free_castorder(&order);
free_castorder(&co);
test_cleanup();
}

View file

@ -44,6 +44,7 @@ static void test_magicresistance_unit(CuTest *tc) {
msg = c->type->curseinfo(u2, TYP_UNIT, c, 1);
CuAssertPtrNotNull(tc, msg);
CuAssertStrEquals(tc, "curseinfo::magicresistance_unit", test_get_messagetype(msg));
msg_release(msg);
test_cleanup();
}
@ -70,7 +71,7 @@ static void test_magicresistance_building(CuTest *tc) {
msg = c->type->curseinfo(b1, TYP_BUILDING, c, 1);
CuAssertPtrNotNull(tc, msg);
CuAssertStrEquals(tc, "curseinfo::magicresistance_building", test_get_messagetype(msg));
msg_release(msg);
test_cleanup();
}

View file

@ -3,10 +3,42 @@
#include <kernel/config.h>
#include <CuTest.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <util/log.h>
#pragma warning(disable: 4210)
typedef struct suite {
struct suite *next;
CuSuite *csuite;
char *name;
} suite;
static suite *suites;
static void add_suite(CuSuite *(*csuite)(void), const char *name, int argc, char *argv[]) {
suite *s = 0;
if (argc > 0) {
int i;
for (i = 0; i != argc; ++i) {
if (strcmp(argv[i], name) == 0) {
s = malloc(sizeof(suite));
break;
}
}
}
else {
s = malloc(sizeof(suite));
}
if (s) {
s->next = suites;
s->name = _strdup(name);
s->csuite = csuite();
suites = s;
}
}
void RunTests(CuSuite * suite, const char *name) {
CuString *output = CuStringNew();
@ -17,95 +49,115 @@ void RunTests(CuSuite * suite, const char *name) {
CuStringDelete(output);
}
#define RUN_TESTS(suite, name) \
bool list = false;
#define ADD_SUITE(name) \
CuSuite *get_##name##_suite(void); \
CuSuite *name = get_##name##_suite(); \
RunTests(name, #name); \
suite->failCount += name->failCount; \
suite->count += name->count; \
CuSuiteDelete(name);
if (list) printf("%s\n", #name); \
if (!list || argc>0) add_suite(get_##name##_suite, #name, argc, argv)
int RunAllTests(void)
int RunAllTests(int argc, char *argv[])
{
CuSuite *suite = CuSuiteNew();
int fail_count, flags = log_flags;
int flags = log_flags;
log_flags = LOG_FLUSH | LOG_CPERROR;
game_init();
log_flags = LOG_FLUSH | LOG_CPERROR;
/* self-test */
RUN_TESTS(suite, tests);
RUN_TESTS(suite, callback);
RUN_TESTS(suite, seen);
RUN_TESTS(suite, json);
RUN_TESTS(suite, jsonconf);
RUN_TESTS(suite, direction);
RUN_TESTS(suite, skill);
RUN_TESTS(suite, keyword);
RUN_TESTS(suite, order);
RUN_TESTS(suite, race);
/* util */
RUN_TESTS(suite, config);
RUN_TESTS(suite, attrib);
RUN_TESTS(suite, base36);
RUN_TESTS(suite, bsdstring);
RUN_TESTS(suite, functions);
RUN_TESTS(suite, parser);
RUN_TESTS(suite, umlaut);
RUN_TESTS(suite, unicode);
RUN_TESTS(suite, strings);
RUN_TESTS(suite, rng);
/* items */
RUN_TESTS(suite, xerewards);
/* kernel */
RUN_TESTS(suite, alliance);
RUN_TESTS(suite, unit);
RUN_TESTS(suite, faction);
RUN_TESTS(suite, group);
RUN_TESTS(suite, build);
RUN_TESTS(suite, pool);
RUN_TESTS(suite, curse);
RUN_TESTS(suite, equipment);
RUN_TESTS(suite, item);
RUN_TESTS(suite, magic);
RUN_TESTS(suite, alchemy);
RUN_TESTS(suite, reports);
RUN_TESTS(suite, save);
RUN_TESTS(suite, ship);
RUN_TESTS(suite, spellbook);
RUN_TESTS(suite, building);
RUN_TESTS(suite, spell);
RUN_TESTS(suite, spells);
RUN_TESTS(suite, magicresistance);
RUN_TESTS(suite, ally);
RUN_TESTS(suite, messages);
/* gamecode */
RUN_TESTS(suite, prefix);
RUN_TESTS(suite, battle);
RUN_TESTS(suite, donations);
RUN_TESTS(suite, travelthru);
RUN_TESTS(suite, economy);
RUN_TESTS(suite, give);
RUN_TESTS(suite, laws);
RUN_TESTS(suite, market);
RUN_TESTS(suite, move);
RUN_TESTS(suite, piracy);
RUN_TESTS(suite, stealth);
RUN_TESTS(suite, upkeep);
RUN_TESTS(suite, vortex);
RUN_TESTS(suite, wormhole);
RUN_TESTS(suite, spy);
RUN_TESTS(suite, study);
/* self-test */
ADD_SUITE(tests);
ADD_SUITE(callback);
ADD_SUITE(seen);
ADD_SUITE(json);
ADD_SUITE(jsonconf);
ADD_SUITE(direction);
ADD_SUITE(skill);
ADD_SUITE(keyword);
ADD_SUITE(order);
ADD_SUITE(race);
/* util */
ADD_SUITE(config);
ADD_SUITE(attrib);
ADD_SUITE(base36);
ADD_SUITE(bsdstring);
ADD_SUITE(functions);
ADD_SUITE(parser);
ADD_SUITE(umlaut);
ADD_SUITE(unicode);
ADD_SUITE(strings);
ADD_SUITE(rng);
/* items */
ADD_SUITE(xerewards);
/* kernel */
ADD_SUITE(alliance);
ADD_SUITE(unit);
ADD_SUITE(faction);
ADD_SUITE(group);
ADD_SUITE(build);
ADD_SUITE(pool);
ADD_SUITE(curse);
ADD_SUITE(equipment);
ADD_SUITE(item);
ADD_SUITE(magic);
ADD_SUITE(alchemy);
ADD_SUITE(reports);
ADD_SUITE(save);
ADD_SUITE(ship);
ADD_SUITE(spellbook);
ADD_SUITE(building);
ADD_SUITE(spell);
ADD_SUITE(spells);
ADD_SUITE(magicresistance);
ADD_SUITE(ally);
ADD_SUITE(messages);
/* gamecode */
ADD_SUITE(prefix);
ADD_SUITE(battle);
ADD_SUITE(donations);
ADD_SUITE(travelthru);
ADD_SUITE(economy);
ADD_SUITE(give);
ADD_SUITE(laws);
ADD_SUITE(market);
ADD_SUITE(move);
ADD_SUITE(piracy);
ADD_SUITE(stealth);
ADD_SUITE(upkeep);
ADD_SUITE(vortex);
ADD_SUITE(wormhole);
ADD_SUITE(spy);
ADD_SUITE(study);
printf("\ntest summary: %d tests, %d failed\n", suite->count, suite->failCount);
log_flags = flags;
fail_count = suite->failCount;
CuSuiteDelete(suite);
game_done();
return fail_count;
if (suites) {
CuSuite *summary = CuSuiteNew();
int fail_count;
game_init();
while (suites) {
suite *s = suites->next;
RunTests(suites->csuite, suites->name);
summary->failCount += suites->csuite->failCount;
summary->count += suites->csuite->count;
CuSuiteDelete(suites->csuite);
free(suites->name);
free(suites);
suites = s;
}
printf("\ntest summary: %d tests, %d failed\n", summary->count, summary->failCount);
log_flags = flags;
fail_count = summary->failCount;
CuSuiteDelete(summary);
game_done();
return fail_count;
}
return 0;
}
int main(int argc, char ** argv) {
log_stderr = 0;
return RunAllTests();
++argv;
--argc;
if (argc > 0 && strcmp("--list", argv[0]) == 0) {
list = true;
++argv;
--argc;
}
return RunAllTests(argc, argv);
}

View file

@ -9,6 +9,7 @@
#include <kernel/terrain.h>
#include <kernel/item.h>
#include <kernel/unit.h>
#include <kernel/order.h>
#include <kernel/race.h>
#include <kernel/faction.h>
#include <kernel/building.h>
@ -79,6 +80,7 @@ void test_cleanup(void)
global.functions.wage = NULL;
free_params(&global.parameters);
default_locale = 0;
close_orders();
free_locales();
free_spells();
free_buildingtypes();
@ -95,10 +97,6 @@ void test_cleanup(void)
for (i = 0; i != MAXKEYWORDS; ++i) {
enable_keyword(i, true);
}
if (!mt_find("missing_message")) {
mt_register(mt_new_va("missing_message", "name:string", 0));
mt_register(mt_new_va("missing_feedback", "unit:unit", "region:region", "command:order", "name:string", 0));
}
if (errno) {
int error = errno;
errno = 0;
@ -152,16 +150,19 @@ building_type * test_create_buildingtype(const char * name)
{
building_type *btype = bt_get_or_create(name);
btype->flags = BTF_NAMECHANGE;
btype->_name = _strdup(name);
btype->construction = (construction *)calloc(sizeof(construction), 1);
btype->construction->skill = SK_BUILDING;
btype->construction->maxsize = -1;
btype->construction->minskill = 1;
btype->construction->reqsize = 1;
btype->construction->materials = (requirement *)calloc(sizeof(requirement), 2);
btype->construction->materials[1].number = 0;
btype->construction->materials[0].number = 1;
btype->construction->materials[0].rtype = get_resourcetype(R_STONE);
if (!btype->construction) {
btype->construction = (construction *)calloc(sizeof(construction), 1);
btype->construction->skill = SK_BUILDING;
btype->construction->maxsize = -1;
btype->construction->minskill = 1;
btype->construction->reqsize = 1;
}
if (!btype->construction->materials) {
btype->construction->materials = (requirement *)calloc(sizeof(requirement), 2);
btype->construction->materials[1].number = 0;
btype->construction->materials[0].number = 1;
btype->construction->materials[0].rtype = get_resourcetype(R_STONE);
}
if (default_locale) {
locale_setstring(default_locale, name, name);
}
@ -280,8 +281,11 @@ struct message * test_find_messagetype(struct message_list *msgs, const char *na
}
void test_clear_messages(faction *f) {
free_messagelist(f->msgs);
f->msgs = 0;
if (f->msgs) {
free_messagelist(f->msgs->begin);
free(f->msgs);
f->msgs = 0;
}
}
void disabled_test(void *suite, void (*test)(CuTest *), const char *name) {

View file

@ -38,13 +38,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <assert.h>
#include <string.h>
static void travel_done(attrib *a) {
quicklist *ql = (quicklist *)a->data.v;
ql_free(ql);
}
/*********************/
/* at_travelunit */
/*********************/
attrib_type at_travelunit = {
"travelunit",
DEFAULT_INIT,
DEFAULT_FINALIZE,
travel_done,
DEFAULT_AGE,
NO_WRITE,
NO_READ

View file

@ -35,7 +35,7 @@ static void setup_travelthru(travel_fixture *fix, int nunits) {
}
f = test_create_faction(0);
while (nunits--) {
unit *u = test_create_unit(f, 0);
unit *u = test_create_unit(f, test_create_region(1, 0, 0));
travelthru_add(r, u);
}
fix->r = r;

View file

@ -94,6 +94,7 @@ void free_triggers(trigger * triggers)
trigger *t = triggers;
triggers = t->next;
t_free(t);
free(t);
}
}

View file

@ -48,3 +48,7 @@ void register_function(pf_generic fun, const char *name)
len = cb_new_kv(name, len, &fun, sizeof(fun), buffer);
cb_insert(&cb_functions, buffer, len);
}
void free_functions(void) {
cb_clear(&cb_functions);
}

View file

@ -26,6 +26,7 @@ extern "C" {
pf_generic get_function(const char *name);
void register_function(pf_generic fun, const char *name);
void free_functions(void);
#ifdef __cplusplus
}

View file

@ -315,9 +315,23 @@ void reset_locales(void) {
void free_locales(void) {
locale_init = 0;
while (locales) {
int i;
int i, index = locales->index;
locale * next = locales->next;
for (i = UT_PARAMS; i != UT_RACES; ++i) {
struct critbit_tree ** cb = (struct critbit_tree **)get_translations(locales, i);
if (*cb) {
// TODO: this crashes?
cb_clear(*cb);
free(*cb);
}
}
for (i = UT_RACES; i != UT_MAX; ++i) {
void *tokens = lstrs[index].tokens[i];
if (tokens) {
freetokens(tokens);
}
}
for (i = 0; i != SMAXHASH; ++i) {
while (locales->strings[i]) {
struct locale_str * strings = locales->strings[i];

View file

@ -155,7 +155,7 @@ void addtoken(void ** root, const char *str, variant id)
next = next->nexthash;
if (!next) {
tref *ref;
tnode *node = (tnode *)calloc(1, sizeof(tnode));
tnode *node = (tnode *)calloc(1, sizeof(tnode)); // TODO: what is the reason for this empty node to exist?
if (ucs < 'a' || ucs > 'z') {
lcs = towlower((wint_t)ucs);
@ -166,6 +166,7 @@ void addtoken(void ** root, const char *str, variant id)
ref = (tref *)malloc(sizeof(tref));
ref->ucs = ucs;
ref->node = 0;
ref->node = node;
ref->nexthash = tk->next[index];
tk->next[index] = ref;
@ -216,6 +217,7 @@ void freetokens(void * root)
while (*refs) {
tref * ref = *refs;
*refs = ref->nexthash;
// free(ref->node);
free(ref);
}
}

View file

@ -49,8 +49,12 @@ static void test_umlaut(CuTest * tc)
CuAssertIntEquals(tc, E_TOK_SUCCESS, result);
CuAssertIntEquals(tc, 1, id.i);
result = findtoken(tokens, "DERP", &id);
CuAssertIntEquals(tc, E_TOK_SUCCESS, result);
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "derp", &id));
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "Derp", &id));
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "dErp", &id));
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "deRp", &id));
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "derP", &id));
CuAssertIntEquals(tc, E_TOK_SUCCESS, findtoken(tokens, "DERP", &id));
CuAssertIntEquals(tc, 2, id.i);
result = findtoken(tokens, umlauts, &id);