simple tests for build().

cleaning up the code to give it a common setup function.
change the golem code to use flag, not hard-coded race.
unify the golems, make code more readable, kill a block of unused code.
This commit is contained in:
Enno Rehling 2014-08-24 17:09:32 +02:00
parent 9db6826662
commit 7d17cafdd6
5 changed files with 267 additions and 235 deletions

View File

@ -79,8 +79,7 @@ extern "C" {
void sunhash(struct ship *sh);
extern int roqf_factor(void);
extern int build(struct unit *u, const construction * ctype, int completed,
int want);
int build(struct unit *u, const construction * ctype, int completed, int want);
extern int maxbuild(const struct unit *u, const construction * cons);
extern struct message *msg_materials_required(struct unit *u,
struct order *ord, const struct construction *ctype, int multi);

View File

@ -13,86 +13,110 @@
#include <CuTest.h>
#include <tests.h>
#include <stdlib.h>
#include <assert.h>
static void test_build_building_no_materials(CuTest *tc) {
typedef struct build_fixture {
faction *f;
unit *u;
region *r;
faction *f;
race *rc;
const building_type *btype;
} build_fixture;
static unit * setup_build(build_fixture *bf) {
test_cleanup();
test_create_world();
bf->rc = test_create_race("human");
bf->r = findregion(0, 0);
bf->f = test_create_faction(bf->rc);
assert(bf->rc && bf->f && bf->r);
bf->u = test_create_unit(bf->f, bf->r);
assert(bf->u);
return bf->u;
}
rc = test_create_race("human");
r = findregion(0, 0);
f = test_create_faction(rc);
assert(rc && f && r);
u = test_create_unit(f, r);
static void test_build(CuTest *tc) {
build_fixture bf;
unit *u;
construction cons = { 0 };
const struct resource_type *rtype;
u = setup_build(&bf);
rtype = get_resourcetype(R_SILVER);
assert(rtype);
cons.materials = calloc(2, sizeof(requirement));
cons.materials[0].number = 1;
cons.materials[0].rtype = rtype;
cons.skill = SK_ARMORER;
cons.minskill = 2;
cons.reqsize = 1;
CuAssertIntEquals(tc, ENEEDSKILL, build(u, &cons, 1, 1));
set_level(u, SK_ARMORER, 1);
CuAssertIntEquals(tc, ELOWSKILL, build(u, &cons, 1, 1));
set_level(u, SK_ARMORER, 2);
CuAssertIntEquals(tc, ENOMATERIALS, build(u, &cons, 1, 1));
i_change(&u->items, rtype->itype, 1);
CuAssertIntEquals(tc, 1, build(u, &cons, 1, 1));
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
scale_number(u, 2);
i_change(&u->items, rtype->itype, 2);
CuAssertIntEquals(tc, 2, build(u, &cons, 2, 2));
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
test_cleanup();
}
static void test_build_building_no_materials(CuTest *tc) {
const building_type *btype;
build_fixture bf = { 0 };
unit *u;
u = setup_build(&bf);
btype = bt_find("castle");
assert(u && btype);
set_level(u, SK_BUILDING, 1);
CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, 0));
CuAssertPtrEquals(tc, 0, r->buildings);
CuAssertPtrEquals(tc, 0, u->building);
assert(btype);
set_level(bf.u, SK_BUILDING, 1);
CuAssertIntEquals(tc, ENOMATERIALS, build_building(bf.u, btype, 0, 4, 0));
CuAssertPtrEquals(tc, 0, bf.r->buildings);
CuAssertPtrEquals(tc, 0, bf.u->building);
}
static void test_build_building_with_golem(CuTest *tc) {
unit *u;
region *r;
faction *f;
race *rc;
build_fixture bf;
const building_type *btype;
test_cleanup();
test_create_world();
rc = test_create_race("stonegolem");
rc->flags |= RCF_STONEGOLEM;
u = setup_build(&bf);
bf.rc->flags |= RCF_STONEGOLEM;
btype = bt_find("castle");
assert(btype && rc);
assert(btype);
assert(btype->construction);
r = findregion(0, 0);
assert(!r->buildings);
f = test_create_faction(rc);
assert(r && f);
u = test_create_unit(f, r);
assert(u);
set_level(u, SK_BUILDING, 1);
set_level(bf.u, SK_BUILDING, 1);
CuAssertIntEquals(tc, 1, build_building(u, btype, 0, 4, 0));
CuAssertPtrNotNull(tc, r->buildings);
CuAssertIntEquals(tc, 1, r->buildings->size);
CuAssertPtrNotNull(tc, u->region->buildings);
CuAssertIntEquals(tc, 1, u->region->buildings->size);
CuAssertIntEquals(tc, 0, u->number);
}
static void test_build_building_success(CuTest *tc) {
unit *u;
region *r;
faction *f;
race *rc;
build_fixture bf = { 0 };
const building_type *btype;
const resource_type *rtype;
test_cleanup();
test_create_world();
u = setup_build(&bf);
rc = test_create_race("human");
rtype = get_resourcetype(R_STONE);
btype = bt_find("castle");
assert(btype && rc && rtype && rtype->itype);
assert(btype && rtype && rtype->itype);
assert(btype->construction);
r = findregion(0, 0);
assert(!r->buildings);
f = test_create_faction(rc);
assert(r && f);
u = test_create_unit(f, r);
assert(u);
i_change(&u->items, rtype->itype, 1);
assert(!u->region->buildings);
i_change(&bf.u->items, rtype->itype, 1);
set_level(u, SK_BUILDING, 1);
CuAssertIntEquals(tc, 1, build_building(u, btype, 0, 4, 0));
CuAssertPtrNotNull(tc, r->buildings);
CuAssertPtrEquals(tc, r->buildings, u->building);
CuAssertPtrNotNull(tc, u->region->buildings);
CuAssertPtrEquals(tc, u->region->buildings, u->building);
CuAssertIntEquals(tc, 1, u->building->size);
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
}
@ -100,6 +124,7 @@ static void test_build_building_success(CuTest *tc) {
CuSuite *get_build_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_build);
SUITE_ADD_TEST(suite, test_build_building_success);
SUITE_ADD_TEST(suite, test_build_building_with_golem);
SUITE_ADD_TEST(suite, test_build_building_no_materials);

View File

@ -101,24 +101,29 @@ static int res_changepeasants(unit * u, const resource_type * rtype, int delta)
return u->region->land->peasants;
}
static int golem_factor(const unit *u, const resource_type *rtype) {
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM)) {
return GOLEM_STONE;
}
if (rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM)) {
return GOLEM_IRON;
}
return 0;
}
static int res_changeitem(unit * u, const resource_type * rtype, int delta)
{
int num;
if (rtype == get_resourcetype(R_STONE) && u_race(u) == get_race(RC_STONEGOLEM)
&& delta <= 0) {
int reduce = delta / GOLEM_STONE;
if (delta % GOLEM_STONE != 0)
int gf = (delta>0) ? 0 : golem_factor(u, rtype);
if (gf>0) {
if (delta != 0) {
int reduce = delta / gf;
if (delta % gf != 0) {
--reduce;
scale_number(u, u->number + reduce);
num = u->number * GOLEM_STONE;
}
else if (rtype == get_resourcetype(R_IRON)
&& u_race(u) == get_race(RC_IRONGOLEM) && delta <= 0) {
int reduce = delta / GOLEM_IRON;
if (delta % GOLEM_IRON != 0)
--reduce;
scale_number(u, u->number + reduce);
num = u->number * GOLEM_IRON;
if (reduce) scale_number(u, u->number + reduce);
}
num = u->number * gf;
}
else {
const item_type *itype = resource2item(rtype);

View File

@ -1,7 +1,7 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -53,18 +53,14 @@ int get_resource(const unit * u, const resource_type * rtype)
return i;
}
if (rtype->itype) {
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM)) {
return u->number * GOLEM_STONE;
} else if (rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM)) {
return u->number * GOLEM_IRON;
} else {
return i_get(u->items, rtype->itype);
}
}
if (rtype == get_resourcetype(R_AURA))
if (rtype == get_resourcetype(R_AURA)) {
return get_spellpoints(u);
if (rtype == get_resourcetype(R_PERMAURA))
}
if (rtype == get_resourcetype(R_PERMAURA)) {
return max_spellpoints(u->region, u);
}
log_error("trying to get unknown resource '%s'.\n", rtype->_name[0]);
return 0;
}
@ -81,7 +77,7 @@ int change_resource(unit * u, const resource_type * rtype, int change)
i = change_maxspellpoints(u, change);
else
assert(!"undefined resource detected. rtype->uchange not initialized.");
assert(i==get_resource(u, rtype));
assert(i == get_resource(u, rtype));
assert(i >= 0);
if (i >= 100000000) {
log_warning("%s has %d %s\n", unitname(u), i, rtype->_name[0]);
@ -118,11 +114,13 @@ int change_reservation(unit * u, const resource_type * rtype, int value)
*rp = res = calloc(sizeof(reservation), 1);
res->type = rtype;
res->value = value;
} else if (res && res->value + value <= 0) {
}
else if (res && res->value + value <= 0) {
*rp = res->next;
free(res);
return 0;
} else {
}
else {
res->value += value;
}
return res->value;
@ -141,11 +139,13 @@ int set_resvalue(unit * u, const resource_type * rtype, int value)
*rp = res = calloc(sizeof(reservation), 1);
res->type = rtype;
res->value = value;
} else if (res && value <= 0) {
}
else if (res && value <= 0) {
*rp = res->next;
free(res);
return 0;
} else {
}
else {
res->value = value;
}
return res->value;
@ -153,7 +153,7 @@ int set_resvalue(unit * u, const resource_type * rtype, int value)
int
get_pooled(const unit * u, const resource_type * rtype, unsigned int mode,
int count)
int count)
{
const faction *f = u->faction;
unit *v;
@ -187,7 +187,8 @@ get_pooled(const unit * u, const resource_type * rtype, unsigned int mode,
if (v->faction == f) {
mask = (mode >> 3) & (GET_SLACK | GET_RESERVE);
} else if (alliedunit(v, f, HELP_MONEY))
}
else if (alliedunit(v, f, HELP_MONEY))
mask = (mode >> 6) & (GET_SLACK | GET_RESERVE);
else
continue;
@ -212,14 +213,16 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
if ((mode & GET_SLACK) && (mode & GET_RESERVE)) {
n = _min(use, have);
} else {
}
else {
int reserve = get_reservation(u, rtype);
int slack = _max(0, have - reserve);
if (mode & GET_RESERVE) {
n = have - slack;
n = _min(use, n);
change_reservation(u, rtype, -n);
} else if (mode & GET_SLACK) {
}
else if (mode & GET_SLACK) {
n = _min(use, slack);
}
}
@ -239,7 +242,8 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
if (v->faction == f) {
mask = (mode >> 3) & (GET_SLACK | GET_RESERVE);
} else if (alliedunit(v, f, HELP_MONEY))
}
else if (alliedunit(v, f, HELP_MONEY))
mask = (mode >> 6) & (GET_SLACK | GET_RESERVE);
else
continue;

View File

@ -16,7 +16,6 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <autoconf.h>
#include <platform.h>
#include <util/log.h>