forked from github/server
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:
parent
eea99e2fd3
commit
d43265f937
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
13
src/study.c
13
src/study.c
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue