forked from github/server
Merge branch 'develop' of github.com:ennorehling/eressea into develop
This commit is contained in:
commit
3081a89f1c
|
@ -11,6 +11,7 @@ addons:
|
||||||
- libncurses5-dev
|
- libncurses5-dev
|
||||||
- libsqlite3-dev
|
- libsqlite3-dev
|
||||||
- libxml2-dev
|
- libxml2-dev
|
||||||
|
- valgrind
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
|
|
@ -6,13 +6,19 @@ function setup()
|
||||||
conf = [[{
|
conf = [[{
|
||||||
"races" : { "human" : {} },
|
"races" : { "human" : {} },
|
||||||
"terrains" : { "plain" : { "flags" : [ "land" ] } },
|
"terrains" : { "plain" : { "flags" : [ "land" ] } },
|
||||||
"keywords" : { "de" : { "study": "LERNEN" } },
|
"keywords" : { "de" : { "study": "LERNEN", "teach": "LEHREN" } },
|
||||||
"skills" : { "de": { "alchemy" : "Alchemie", "crossbow" : "Armbrust" } },
|
"skills" : { "de": {
|
||||||
|
"tactics" : "Taktik",
|
||||||
|
"alchemy" : "Alchemie",
|
||||||
|
"crossbow" : "Armbrust"
|
||||||
|
} },
|
||||||
"spells" : { "fireball" : { "syntax" : "u+" } }
|
"spells" : { "fireball" : { "syntax" : "u+" } }
|
||||||
}]]
|
}]]
|
||||||
eressea.game.reset()
|
eressea.game.reset()
|
||||||
eressea.config.reset();
|
eressea.config.reset();
|
||||||
eressea.settings.set('rules.magic.playerschools', '')
|
eressea.settings.set('rules.magic.playerschools', '')
|
||||||
|
eressea.settings.set("rules.economy.food", "4")
|
||||||
|
eressea.settings.set('study.random_progress', '0')
|
||||||
eressea.config.parse(conf)
|
eressea.config.parse(conf)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,3 +57,62 @@ function test_unit_spells()
|
||||||
assert_equal("fireball", sp.name)
|
assert_equal("fireball", sp.name)
|
||||||
assert_equal(2, sp.level)
|
assert_equal(2, sp.level)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function make_teacher(student, f, skill)
|
||||||
|
f = f or student.faction
|
||||||
|
local u = unit.create(f, student.region, 1)
|
||||||
|
u:clear_orders()
|
||||||
|
u:add_order("LEHRE " .. itoa36(student.id))
|
||||||
|
u:set_skill(skill or "crossbow", 10)
|
||||||
|
return u
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_student(f, r, num, skill)
|
||||||
|
local u = unit.create(f, r, num or 1)
|
||||||
|
u:clear_orders()
|
||||||
|
u:add_order("LERNE " .. (skill or "Armbrust"))
|
||||||
|
return u
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_study_no_teacher()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("test@example.com", "human", "de")
|
||||||
|
local u1 = make_student(f, r, 1)
|
||||||
|
u1:set_skill("crossbow", 1)
|
||||||
|
process_orders()
|
||||||
|
assert_equal(1, u1:get_skill("crossbow"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_study_with_teacher()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("test@example.com", "human", "de")
|
||||||
|
local u1 = make_student(f, r, 1)
|
||||||
|
|
||||||
|
make_teacher(u1)
|
||||||
|
u1:set_skill("crossbow", 1)
|
||||||
|
process_orders()
|
||||||
|
assert_equal(2, u1:get_skill("crossbow"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_study_too_many_students()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("test@example.com", "human", "de")
|
||||||
|
local u1 = make_student(f, r, 20, "Taktik")
|
||||||
|
u1.name = "Student"
|
||||||
|
u1:add_item("money", 201*u1.number)
|
||||||
|
make_teacher(u1, f, "tactics")
|
||||||
|
process_orders()
|
||||||
|
assert_equal(u1.number, u1:get_item("money"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_study_multiple_teachers()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local f = faction.create("test@example.com", "human", "de")
|
||||||
|
local u1 = make_student(f, r, 20, "Taktik")
|
||||||
|
u1.name = "Student"
|
||||||
|
u1:add_item("money", 201*u1.number)
|
||||||
|
make_teacher(u1, f, "tactics")
|
||||||
|
make_teacher(u1, f, "tactics")
|
||||||
|
process_orders()
|
||||||
|
assert_equal(u1.number, u1:get_item("money"))
|
||||||
|
end
|
||||||
|
|
|
@ -193,6 +193,7 @@ set(TESTS_SRC
|
||||||
skill.test.c
|
skill.test.c
|
||||||
spells.test.c
|
spells.test.c
|
||||||
spy.test.c
|
spy.test.c
|
||||||
|
study.test.c
|
||||||
upkeep.test.c
|
upkeep.test.c
|
||||||
spells/magicresistance.test.c
|
spells/magicresistance.test.c
|
||||||
${ATTRIBUTES_TESTS}
|
${ATTRIBUTES_TESTS}
|
||||||
|
|
|
@ -159,7 +159,7 @@ void process_quit(void) {
|
||||||
|
|
||||||
void process_study(void) {
|
void process_study(void) {
|
||||||
process_cmd(K_TEACH, teach_cmd, PROC_LONG_ORDER);
|
process_cmd(K_TEACH, teach_cmd, PROC_LONG_ORDER);
|
||||||
process_cmd(K_STUDY, learn_cmd, PROC_LONG_ORDER);
|
process_cmd(K_STUDY, study_cmd, PROC_LONG_ORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_movement(void) {
|
void process_movement(void) {
|
||||||
|
|
|
@ -59,9 +59,11 @@ static int report_json(const char *filename, report_context * ctx, const char *c
|
||||||
if (sr) {
|
if (sr) {
|
||||||
terrain_t ter = oldterrain(r->terrain);
|
terrain_t ter = oldterrain(r->terrain);
|
||||||
if (ter == NOTERRAIN) {
|
if (ter == NOTERRAIN) {
|
||||||
log_warning("report_json: %s has no terrain id\n", r->terrain->_name);
|
data = 1 + r->terrain->_name[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data = 1 + (int)ter;
|
||||||
}
|
}
|
||||||
data = 1 + (int)ter;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(F, "%d", data);
|
fprintf(F, "%d", data);
|
||||||
|
|
|
@ -115,7 +115,9 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
assert(str);
|
assert(str);
|
||||||
if (text) --size;
|
if (text) --size;
|
||||||
bytes = (int)strlcpy(bufp, str, size);
|
bytes = (int)strlcpy(bufp, str, size);
|
||||||
if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER();
|
if (wrptr(&bufp, &size, bytes) != 0) {
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
|
}
|
||||||
if (text) *bufp++ = ' ';
|
if (text) *bufp++ = ' ';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -127,8 +127,7 @@ const struct terrain_type *newterrain(terrain_t t)
|
||||||
terrain_t oldterrain(const struct terrain_type * terrain)
|
terrain_t oldterrain(const struct terrain_type * terrain)
|
||||||
{
|
{
|
||||||
terrain_t t;
|
terrain_t t;
|
||||||
if (terrain == NULL)
|
assert(terrain);
|
||||||
return NOTERRAIN;
|
|
||||||
for (t = 0; t != MAXTERRAINS; ++t) {
|
for (t = 0; t != MAXTERRAINS; ++t) {
|
||||||
if (newterrains[t] == terrain)
|
if (newterrains[t] == terrain)
|
||||||
return t;
|
return t;
|
||||||
|
|
|
@ -4461,7 +4461,7 @@ void init_processor(void)
|
||||||
add_proc_order(p, K_TEACH, teach_cmd, PROC_THISORDER | PROC_LONGORDER,
|
add_proc_order(p, K_TEACH, teach_cmd, PROC_THISORDER | PROC_LONGORDER,
|
||||||
"Lehren");
|
"Lehren");
|
||||||
p += 10;
|
p += 10;
|
||||||
add_proc_order(p, K_STUDY, learn_cmd, PROC_THISORDER | PROC_LONGORDER,
|
add_proc_order(p, K_STUDY, study_cmd, PROC_THISORDER | PROC_LONGORDER,
|
||||||
"Lernen");
|
"Lernen");
|
||||||
|
|
||||||
p += 10;
|
p += 10;
|
||||||
|
|
|
@ -2295,7 +2295,7 @@ static void eval_race(struct opstack **stack, const void *userdata)
|
||||||
static void eval_order(struct opstack **stack, const void *userdata)
|
static void eval_order(struct opstack **stack, const void *userdata)
|
||||||
{ /* order -> string */
|
{ /* order -> string */
|
||||||
const struct order *ord = (const struct order *)opop(stack).v;
|
const struct order *ord = (const struct order *)opop(stack).v;
|
||||||
char buf[512];
|
char buf[4096];
|
||||||
size_t len;
|
size_t len;
|
||||||
variant var;
|
variant var;
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ bool report, int *academy)
|
||||||
teach->teachers[index] = NULL;
|
teach->teachers[index] = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_warning("MAXTEACHERS is too low at %d", MAXTEACHERS);
|
log_error("MAXTEACHERS=%d is too low for student %s, teacher %s", MAXTEACHERS, unitname(student), unitname(teacher));
|
||||||
}
|
}
|
||||||
teach->value += n;
|
teach->value += n;
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ static double study_speedup(unit * u, skill_t s, study_rule_t rule)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int learn_cmd(unit * u, order * ord)
|
int study_cmd(unit * u, order * ord)
|
||||||
{
|
{
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
int p;
|
int p;
|
||||||
|
|
|
@ -20,19 +20,20 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define H_KRNL_STUDY
|
#define H_KRNL_STUDY
|
||||||
|
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
|
#include <kernel/types.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int teach_cmd(struct unit *u, struct order *ord);
|
extern int teach_cmd(struct unit *u, struct order *ord);
|
||||||
extern int learn_cmd(struct unit *u, struct order *ord);
|
extern int study_cmd(struct unit *u, struct order *ord);
|
||||||
|
|
||||||
extern magic_t getmagicskill(const struct locale *lang);
|
extern magic_t getmagicskill(const struct locale *lang);
|
||||||
extern bool is_migrant(struct unit *u);
|
extern bool is_migrant(struct unit *u);
|
||||||
extern int study_cost(struct unit *u, skill_t talent);
|
extern int study_cost(struct unit *u, skill_t talent);
|
||||||
|
|
||||||
#define MAXTEACHERS 16
|
#define MAXTEACHERS 20
|
||||||
typedef struct teaching_info {
|
typedef struct teaching_info {
|
||||||
struct unit *teachers[MAXTEACHERS];
|
struct unit *teachers[MAXTEACHERS];
|
||||||
int value;
|
int value;
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <platform.h>
|
||||||
|
|
||||||
|
#include "study.h"
|
||||||
|
|
||||||
|
#include <kernel/unit.h>
|
||||||
|
#include <kernel/faction.h>
|
||||||
|
#include <kernel/order.h>
|
||||||
|
#include <util/message.h>
|
||||||
|
#include <util/language.h>
|
||||||
|
#include <util/base36.h>
|
||||||
|
#include <tests.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unit *u;
|
||||||
|
unit *teachers[2];
|
||||||
|
} study_fixture;
|
||||||
|
|
||||||
|
static void setup_study(study_fixture *fix, skill_t sk) {
|
||||||
|
struct region * r;
|
||||||
|
struct faction *f;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
assert(fix);
|
||||||
|
test_cleanup();
|
||||||
|
test_create_world();
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
f = test_create_faction(0);
|
||||||
|
lang = get_or_create_locale(locale_name(f->locale));
|
||||||
|
locale_setstring(lang, mkname("skill", skillnames[sk]), skillnames[sk]);
|
||||||
|
init_skills(lang);
|
||||||
|
fix->u = test_create_unit(f, r);
|
||||||
|
assert(fix->u);
|
||||||
|
fix->u->thisorder = create_order(K_STUDY, f->locale, "%s", skillnames[sk]);
|
||||||
|
|
||||||
|
fix->teachers[0] = test_create_unit(f, r);
|
||||||
|
assert(fix->teachers[0]);
|
||||||
|
fix->teachers[0]->thisorder = create_order(K_TEACH, f->locale, "%s", itoa36(fix->u->no));
|
||||||
|
|
||||||
|
fix->teachers[1] = test_create_unit(f, r);
|
||||||
|
assert(fix->teachers[1]);
|
||||||
|
fix->teachers[1]->thisorder = create_order(K_TEACH, f->locale, "%s", itoa36(fix->u->no));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_study_no_teacher(CuTest *tc) {
|
||||||
|
study_fixture fix;
|
||||||
|
skill *sv;
|
||||||
|
|
||||||
|
setup_study(&fix, SK_CROSSBOW);
|
||||||
|
study_cmd(fix.u, fix.u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, sv = unit_skill(fix.u, SK_CROSSBOW));
|
||||||
|
CuAssertIntEquals(tc, 1, sv->level);
|
||||||
|
CuAssertIntEquals(tc, 2, sv->weeks);
|
||||||
|
CuAssertPtrEquals(tc, 0, test_get_last_message(fix.u->faction->msgs));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_study_with_teacher(CuTest *tc) {
|
||||||
|
study_fixture fix;
|
||||||
|
skill *sv;
|
||||||
|
|
||||||
|
setup_study(&fix, SK_CROSSBOW);
|
||||||
|
set_level(fix.teachers[0], SK_CROSSBOW, TEACHDIFFERENCE);
|
||||||
|
teach_cmd(fix.teachers[0], fix.teachers[0]->thisorder);
|
||||||
|
CuAssertPtrEquals(tc, 0, test_get_last_message(fix.u->faction->msgs));
|
||||||
|
study_cmd(fix.u, fix.u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, sv = unit_skill(fix.u, SK_CROSSBOW));
|
||||||
|
CuAssertIntEquals(tc, 1, sv->level);
|
||||||
|
CuAssertIntEquals(tc, 1, sv->weeks);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_study_with_bad_teacher(CuTest *tc) {
|
||||||
|
study_fixture fix;
|
||||||
|
skill *sv;
|
||||||
|
message *msg;
|
||||||
|
|
||||||
|
setup_study(&fix, SK_CROSSBOW);
|
||||||
|
teach_cmd(fix.teachers[0], fix.teachers[0]->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, msg = test_get_last_message(fix.u->faction->msgs));
|
||||||
|
CuAssertStrEquals(tc, "teach_asgood", test_get_messagetype(msg));
|
||||||
|
study_cmd(fix.u, fix.u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, sv = unit_skill(fix.u, SK_CROSSBOW));
|
||||||
|
CuAssertIntEquals(tc, 1, sv->level);
|
||||||
|
CuAssertIntEquals(tc, 2, sv->weeks);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_study_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_study_no_teacher);
|
||||||
|
SUITE_ADD_TEST(suite, test_study_with_teacher);
|
||||||
|
SUITE_ADD_TEST(suite, test_study_with_bad_teacher);
|
||||||
|
return suite;
|
||||||
|
}
|
|
@ -89,6 +89,7 @@ int RunAllTests(void)
|
||||||
RUN_TESTS(suite, vortex);
|
RUN_TESTS(suite, vortex);
|
||||||
RUN_TESTS(suite, wormhole);
|
RUN_TESTS(suite, wormhole);
|
||||||
RUN_TESTS(suite, spy);
|
RUN_TESTS(suite, spy);
|
||||||
|
RUN_TESTS(suite, study);
|
||||||
|
|
||||||
printf("\ntest summary: %d tests, %d failed\n", suite->count, suite->failCount);
|
printf("\ntest summary: %d tests, %d failed\n", suite->count, suite->failCount);
|
||||||
log_flags = flags;
|
log_flags = flags;
|
||||||
|
|
15
src/tests.c
15
src/tests.c
|
@ -209,15 +209,20 @@ void test_create_world(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
message * test_get_last_message(message_list *msgs) {
|
message * test_get_last_message(message_list *msgs) {
|
||||||
struct mlist *iter = msgs->begin;
|
if (msgs) {
|
||||||
while (iter->next) {
|
struct mlist *iter = msgs->begin;
|
||||||
iter = iter->next;
|
while (iter->next) {
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
return iter->msg;
|
||||||
}
|
}
|
||||||
return iter->msg;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * test_get_messagetype(const message *msg) {
|
const char * test_get_messagetype(const message *msg) {
|
||||||
const char * name = msg->type->name;
|
const char * name;
|
||||||
|
assert(msg);
|
||||||
|
name = msg->type->name;
|
||||||
if (strcmp(name, "missing_message") == 0) {
|
if (strcmp(name, "missing_message") == 0) {
|
||||||
name = (const char *)msg->parameters[0].v;
|
name = (const char *)msg->parameters[0].v;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -16,14 +16,25 @@ while [ ! -d $ROOT/.git ]; do
|
||||||
ROOT=`dirname $ROOT`
|
ROOT=`dirname $ROOT`
|
||||||
done
|
done
|
||||||
|
|
||||||
|
set -e
|
||||||
cd $ROOT/tests
|
cd $ROOT/tests
|
||||||
setup
|
setup
|
||||||
cleanup
|
cleanup
|
||||||
valgrind ../Debug/eressea/eressea -t 184 ../scripts/reports.lua
|
VALGRIND=`which valgrind`
|
||||||
|
SERVER=../Debug/eressea/eressea
|
||||||
|
if [ -n "$VALGRIND" ]; then
|
||||||
|
SUPP=../share/ubuntu-12_04.supp
|
||||||
|
SERVER="$VALGRIND --suppressions=$SUPP --error-exitcode=1 --leak-check=no $SERVER"
|
||||||
|
fi
|
||||||
|
echo "running $SERVER"
|
||||||
|
$SERVER -t 184 ../scripts/reports.lua
|
||||||
[ -d reports ] || quit 4 "no reports directory created"
|
[ -d reports ] || quit 4 "no reports directory created"
|
||||||
CRFILE=184-zvto.cr
|
CRFILE=184-zvto.cr
|
||||||
grep -q FACTION reports/$CRFILE || quit 1 "CR did not contain any factions"
|
grep -q PARTEI reports/$CRFILE || quit 1 "CR did not contain any factions"
|
||||||
grep -q REGION reports/$CRFILE || quit 2 "CR did not contain any regions"
|
grep -q REGION reports/$CRFILE || quit 2 "CR did not contain any regions"
|
||||||
grep -q EINHEIT reports/$CRFILE || quit 3 "CR did not contain any units"
|
grep -q SCHIFF reports/$CRFILE || quit 3 "CR did not contain any ships"
|
||||||
|
grep -q BURG reports/$CRFILE || quit 4 "CR did not contain any buildings"
|
||||||
|
grep -q EINHEIT reports/$CRFILE || quit 5 "CR did not contain any units"
|
||||||
|
grep -q GEGENSTAENDE reports/$CRFILE || quit 6 "CR did not contain any items"
|
||||||
echo "integration tests: PASS"
|
echo "integration tests: PASS"
|
||||||
cleanup
|
cleanup
|
||||||
|
|
Loading…
Reference in New Issue