From a6fe697c7a0d394e7f72563a24a15134633ce9c6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 17 Feb 2016 13:55:48 +0100 Subject: [PATCH] tests for read/write of triggers that reference factions, with bugfixes. --- src/kernel/save.c | 1 + src/kernel/save.test.c | 104 ++++++++++++++++++++++++++++++++++- src/triggers/changefaction.c | 8 ++- src/triggers/createunit.c | 26 +++++---- 4 files changed, 125 insertions(+), 14 deletions(-) diff --git a/src/kernel/save.c b/src/kernel/save.c index fe8fbd93d..94b6e55df 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -761,6 +761,7 @@ void write_unit(struct gamedata *data, const unit * u) const race *irace = u_irace(u); write_unit_reference(u, data->store); + assert(u->faction->_alive); write_faction_reference(u->faction, data->store); WRITE_STR(data->store, u->_name); WRITE_STR(data->store, u->display ? u->display : ""); diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index b39a4cc1e..b30286123 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -6,7 +6,13 @@ #include "group.h" #include "ally.h" #include "faction.h" +#include "region.h" #include "version.h" +#include +#include +#include +#include +#include #include #include @@ -63,13 +69,13 @@ static void test_readwrite_unit(CuTest * tc) test_cleanup(); } -static void test_readwrite_dead_faction(CuTest *tc) { +static void test_readwrite_dead_faction_group(CuTest *tc) { faction *f, *f2; unit * u; group *g; ally *al; int fno; - + test_cleanup(); f = test_create_faction(0); fno = f->no; @@ -103,11 +109,103 @@ static void test_readwrite_dead_faction(CuTest *tc) { test_cleanup(); } +static void test_readwrite_dead_faction_regionowner(CuTest *tc) { + faction *f; + region *r; + unit * u; + int fno; + + test_cleanup(); + config_set("rules.region_owners", "1"); + f = test_create_faction(0); + fno = f->no; + u = test_create_unit(f, r = test_create_region(0, 0, 0)); + region_set_owner(r, f, turn); + destroyfaction(&factions); + CuAssertTrue(tc, !f->_alive); + remove_empty_units(); + writegame("test.dat"); + free_gamedata(); + f = NULL; + readgame("test.dat", false); + f = factions; + CuAssertPtrEquals(tc, 0, f); + r = regions; + CuAssertPtrNotNull(tc, r); + CuAssertPtrEquals(tc, 0, region_get_owner(r)); + test_cleanup(); +} + +static void test_readwrite_dead_faction_changefaction(CuTest *tc) { + faction *f, *f2; + region *r; + trigger *tr; + unit * u; + + test_cleanup(); + config_set("rules.region_owners", "1"); + f = test_create_faction(0); + f2 = test_create_faction(0); + u = test_create_unit(f2, r = test_create_region(0, 0, 0)); + tr = trigger_changefaction(u, f); + add_trigger(&u->attribs, "timer", trigger_timeout(10, tr)); + CuAssertPtrNotNull(tc, a_find(u->attribs, &at_eventhandler)); + destroyfaction(&factions); + CuAssertTrue(tc, !f->_alive); + remove_empty_units(); + writegame("test.dat"); + free_gamedata(); + f = NULL; + readgame("test.dat", false); + f = factions; + CuAssertPtrNotNull(tc, f); + r = regions; + CuAssertPtrNotNull(tc, r); + u = r->units; + CuAssertPtrNotNull(tc, u); + CuAssertPtrEquals(tc, 0, a_find(u->attribs, &at_eventhandler)); + test_cleanup(); +} + +static void test_readwrite_dead_faction_createunit(CuTest *tc) { + faction *f, *f2; + region *r; + trigger *tr; + unit * u; + + test_cleanup(); + config_set("rules.region_owners", "1"); + f = test_create_faction(0); + f2 = test_create_faction(0); + u = test_create_unit(f2, r = test_create_region(0, 0, 0)); + tr = trigger_createunit(r, f, f->race, 1); + add_trigger(&u->attribs, "timer", trigger_timeout(10, tr)); + CuAssertPtrNotNull(tc, a_find(u->attribs, &at_eventhandler)); + destroyfaction(&factions); + CuAssertTrue(tc, !f->_alive); + remove_empty_units(); + writegame("test.dat"); + free_gamedata(); + f = NULL; + readgame("test.dat", false); + f = factions; + CuAssertPtrNotNull(tc, f); + r = regions; + CuAssertPtrNotNull(tc, r); + u = r->units; + CuAssertPtrNotNull(tc, u); + CuAssertPtrEquals(tc, 0, a_find(u->attribs, &at_eventhandler)); + test_cleanup(); +} + CuSuite *get_save_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_readwrite_data); SUITE_ADD_TEST(suite, test_readwrite_unit); - SUITE_ADD_TEST(suite, test_readwrite_dead_faction); + SUITE_ADD_TEST(suite, test_readwrite_dead_faction_createunit); + SUITE_ADD_TEST(suite, test_readwrite_dead_faction_changefaction); + SUITE_ADD_TEST(suite, test_readwrite_dead_faction_regionowner); + SUITE_ADD_TEST(suite, test_readwrite_dead_faction_group); return suite; } diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index eb212b769..6aa0de463 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -84,9 +84,15 @@ static void changefaction_write(const trigger * t, struct storage *store) static int changefaction_read(trigger * t, struct storage *store) { + variant var; changefaction_data *td = (changefaction_data *)t->data.v; read_reference(&td->unit, store, read_unit_reference, resolve_unit); - read_reference(&td->faction, store, read_faction_reference, resolve_faction); + var = read_faction_reference(store); + if (var.i == 0) { + return AT_READ_FAIL; + } + ur_add(var, &td->faction, resolve_faction); + // read_reference(&td->faction, store, read_faction_reference, resolve_faction); return AT_READ_OK; } diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index 642e598f0..ee75916b4 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -91,21 +91,27 @@ static void createunit_write(const trigger * t, struct storage *store) static int createunit_read(trigger * t, struct storage *store) { createunit_data *td = (createunit_data *)t->data.v; + variant var; + int result = AT_READ_OK; - int uc = - read_reference(&td->f, store, read_faction_reference, resolve_faction); - int rc = - read_reference(&td->r, store, read_region_reference, + var = read_faction_reference(store); + if (var.i > 0) { + td->f = findfaction(var.i); + if (!td->f) { + ur_add(var, &td->f, resolve_faction); + } + } + else { + result = AT_READ_FAIL; + } + read_reference(&td->r, store, read_region_reference, RESOLVE_REGION(global.data_version)); td->race = (const struct race *)read_race_reference(store).v; - - if (uc == 0 && rc == 0) { - if (!td->f || !td->r) - return AT_READ_FAIL; + if (!td->race) { + result = AT_READ_FAIL; } READ_INT(store, &td->number); - - return AT_READ_OK; + return result; } trigger_type tt_createunit = {