a new test for the happy case of a working academy

dependency injection for learn_skill
memory leak fixes (triggers, armor)
This commit is contained in:
Enno Rehling 2016-03-09 23:20:05 +01:00
parent eea99e2fd3
commit d43265f937
6 changed files with 105 additions and 8 deletions

View File

@ -1203,13 +1203,16 @@ static void free_wtype(weapon_type *wtype) {
int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbdata) { int free_rtype_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
resource_type *rtype; resource_type *rtype;
cb_get_kv(match, &rtype, sizeof(rtype)); cb_get_kv(match, &rtype, sizeof(rtype));
free(rtype->_name);
if (rtype->itype) {
free_itype(rtype->itype);
}
if (rtype->wtype) { if (rtype->wtype) {
free_wtype(rtype->wtype); free_wtype(rtype->wtype);
} }
if (rtype->atype) {
free(rtype->atype);
}
if (rtype->itype) {
free_itype(rtype->itype);
}
free(rtype->_name);
free(rtype); free(rtype);
return 0; return 0;
} }

View File

@ -1,6 +1,7 @@
#include <platform.h> #include <platform.h>
#include <magic.h> #include <magic.h>
#include <kernel/config.h>
#include <kernel/types.h> #include <kernel/types.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/unit.h> #include <kernel/unit.h>
@ -90,7 +91,8 @@ static void setup_sabotage(void) {
test_cleanup(); test_cleanup();
lang = get_or_create_locale("de"); lang = get_or_create_locale("de");
locale_setstring(lang, parameters[P_SHIP], "SCHIFF"); locale_setstring(lang, parameters[P_SHIP], "SCHIFF");
test_create_world(); locale_setstring(lang, parameters[P_ANY], "ALLE");
init_parameters(lang);
init_locales(); init_locales();
} }
@ -100,7 +102,7 @@ static void test_sabotage_self(CuTest *tc) {
order *ord; order *ord;
setup_sabotage(); setup_sabotage();
r = findregion(0, 0); r = test_create_region(0, 0, 0);
assert(r); assert(r);
u = test_create_unit(test_create_faction(NULL), r); u = test_create_unit(test_create_faction(NULL), r);
assert(u && u->faction && u->region == r); assert(u && u->faction && u->region == r);
@ -122,7 +124,7 @@ static void test_sabotage_other_fail(CuTest *tc) {
message *msg; message *msg;
setup_sabotage(); setup_sabotage();
r = findregion(0, 0); r = test_create_region(0, 0, 0);
assert(r); assert(r);
u = test_create_unit(test_create_faction(NULL), r); u = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r);
@ -151,7 +153,7 @@ static void test_sabotage_other_success(CuTest *tc) {
order *ord; order *ord;
setup_sabotage(); setup_sabotage();
r = findregion(0, 0); r = test_create_region(0, 0, 0);
assert(r); assert(r);
u = test_create_unit(test_create_faction(NULL), r); u = test_create_unit(test_create_faction(NULL), r);
u2 = test_create_unit(test_create_faction(NULL), r); u2 = test_create_unit(test_create_faction(NULL), r);

View File

@ -824,9 +824,22 @@ void produceexp(struct unit *u, skill_t sk, int n)
produceexp_ex(u, sk, n, learn_skill); produceexp_ex(u, sk, n, learn_skill);
} }
#ifndef NO_TESTS
static learn_fun inject_learn_fun = 0;
void inject_learn(learn_fun fun) {
inject_learn_fun = fun;
}
#endif
bool learn_skill(unit * u, skill_t sk, double learn_chance) bool learn_skill(unit * u, skill_t sk, double learn_chance)
{ {
skill *sv = u->skills; skill *sv = u->skills;
#ifndef NO_TESTS
if (inject_learn_fun) {
return inject_learn_fun(u, sk, learn_chance);
}
#endif
if (learn_chance < 1.0 && rng_int() % 10000 >= learn_chance * 10000) if (learn_chance < 1.0 && rng_int() % 10000 >= learn_chance * 10000)
if (!chance(learn_chance)) if (!chance(learn_chance))
return false; return false;

View File

@ -26,6 +26,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" { extern "C" {
#endif #endif
struct unit;
int teach_cmd(struct unit *u, struct order *ord); int teach_cmd(struct unit *u, struct order *ord);
int study_cmd(struct unit *u, struct order *ord); int study_cmd(struct unit *u, struct order *ord);
@ -33,7 +35,12 @@ extern "C" {
bool is_migrant(struct unit *u); bool is_migrant(struct unit *u);
int study_cost(struct unit *u, skill_t talent); int study_cost(struct unit *u, skill_t talent);
#ifndef NO_TESTS
typedef bool(*learn_fun)(struct unit *u, skill_t sk, double ch);
void inject_learn(learn_fun fun);
#endif
bool learn_skill(struct unit *u, skill_t sk, double chance); bool learn_skill(struct unit *u, skill_t sk, double chance);
void produceexp(struct unit *u, skill_t sk, int n); void produceexp(struct unit *u, skill_t sk, int n);
void produceexp_ex(struct unit *u, skill_t sk, int n, bool(*learn)(struct unit *, skill_t, double)); void produceexp_ex(struct unit *u, skill_t sk, int n, bool(*learn)(struct unit *, skill_t, double));
#define MAXTEACHERS 20 #define MAXTEACHERS 20

View File

@ -30,6 +30,8 @@ static void setup_locale(struct locale *lang) {
if (!locale_getstring(lang, mkname("skill", skillnames[i]))) if (!locale_getstring(lang, mkname("skill", skillnames[i])))
locale_setstring(lang, mkname("skill", skillnames[i]), skillnames[i]); locale_setstring(lang, mkname("skill", skillnames[i]), skillnames[i]);
} }
locale_setstring(lang, parameters[P_ANY], "ALLE");
init_parameters(lang);
init_skills(lang); init_skills(lang);
} }
@ -162,6 +164,71 @@ static void test_produceexp(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
#define MAXLOG 4
typedef struct log_entry {
unit *u;
skill_t sk;
double ch;
} log_entry;
static log_entry log_learners[MAXLOG];
static int log_size;
static bool log_learn(unit *u, skill_t sk, double ch) {
if (log_size < MAXLOG) {
log_entry * entry = &log_learners[log_size++];
entry->u = u;
entry->sk = sk;
entry->ch = ch;
}
return true;
}
static void test_academy_building(CuTest *tc) {
unit *u, *u1, *u2;
struct locale * loc;
building * b;
message * msg;
test_cleanup();
mt_register(mt_new_va("teach_asgood", "unit:unit", "region:region", "command:order", "student:unit", 0));
random_source_inject_constant(0.0);
init_resources();
loc = get_or_create_locale("de");
setup_locale(loc);
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
scale_number(u, 2);
set_level(u, SK_CROSSBOW, TEACHDIFFERENCE);
u->faction->locale = loc;
u1 = test_create_unit(u->faction, u->region);
scale_number(u1, 15);
u1->thisorder = create_order(K_STUDY, loc, skillnames[SK_CROSSBOW]);
u2 = test_create_unit(u->faction, u->region);
scale_number(u2, 5);
u2->thisorder = create_order(K_STUDY, loc, skillnames[SK_CROSSBOW]);
set_level(u2, SK_CROSSBOW, 1);
u->thisorder = create_order(K_TEACH, loc, "%s %s", itoa36(u1->no), itoa36(u2->no));
b = test_create_building(u->region, test_create_buildingtype("academy"));
b->size = 22;
u_set_building(u, b);
u_set_building(u1, b);
u_set_building(u2, b);
i_change(&u1->items, get_resourcetype(R_SILVER)->itype, 50);
i_change(&u2->items, get_resourcetype(R_SILVER)->itype, 50);
b->flags = BLD_WORKING;
inject_learn(log_learn);
teach_cmd(u, u->thisorder);
inject_learn(0);
CuAssertPtrNotNull(tc, msg = test_find_messagetype(u->faction->msgs, "teach_asgood"));
CuAssertPtrEquals(tc, u, (unit *)(msg)->parameters[0].v);
CuAssertPtrEquals(tc, u2, (unit *)(msg)->parameters[3].v);
CuAssertPtrEquals(tc, u, log_learners[0].u);
CuAssertIntEquals(tc, SK_CROSSBOW, log_learners[0].sk);
CuAssertDblEquals(tc, 0.05, log_learners[0].ch, 0.001);
test_cleanup();
}
CuSuite *get_study_suite(void) CuSuite *get_study_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
@ -169,6 +236,7 @@ CuSuite *get_study_suite(void)
SUITE_ADD_TEST(suite, test_study_with_teacher); SUITE_ADD_TEST(suite, test_study_with_teacher);
SUITE_ADD_TEST(suite, test_study_with_bad_teacher); SUITE_ADD_TEST(suite, test_study_with_bad_teacher);
SUITE_ADD_TEST(suite, test_produceexp); SUITE_ADD_TEST(suite, test_produceexp);
SUITE_ADD_TEST(suite, test_academy_building);
DISABLE_TEST(suite, test_study_bug_2194); DISABLE_TEST(suite, test_study_bug_2194);
return suite; return suite;
} }

View File

@ -24,6 +24,8 @@ static void test_shock(CuTest *tc) {
CuAssertIntEquals(tc, 2, u->hp); CuAssertIntEquals(tc, 2, u->hp);
CuAssertIntEquals(tc, 2, get_spellpoints(u)); CuAssertIntEquals(tc, 2, get_spellpoints(u));
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "shock")); CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "shock"));
t_free(tt);
free(tt);
test_cleanup(); test_cleanup();
} }
@ -41,6 +43,8 @@ static void test_shock_low(CuTest *tc) {
tt->type->handle(tt, u); tt->type->handle(tt, u);
CuAssertIntEquals(tc, 1, u->hp); CuAssertIntEquals(tc, 1, u->hp);
CuAssertIntEquals(tc, 1, get_spellpoints(u)); CuAssertIntEquals(tc, 1, get_spellpoints(u));
t_free(tt);
free(tt);
test_cleanup(); test_cleanup();
} }