Crossfire Server, Trunk  R20513
check_arch.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_arch_c =
3  * "$Id: check_arch.c 15379 2011-11-01 19:40:45Z ryo_saeba $";
4  */
5 
6 /*
7  * CrossFire, A Multiplayer game for X-windows
8  *
9  * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10  * Copyright (C) 1992 Frank Tore Johansen
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * The authors can be reached via e-mail at crossfire-devel@real-time.com
27  */
28 
29 /*
30  * This is the unit tests file for common/arch.c
31  */
32 
33 #include <global.h>
34 #include <stdlib.h>
35 #include <check.h>
36 #include <loader.h>
37 #include <toolkit_common.h>
38 
39 static void setup(void) {
40  cctk_setdatadir(BUILD_ROOT"lib");
41  cctk_setlog(LOGDIR"/unit/common/arch.out");
43 }
44 
45 static void teardown(void) {
46  /* put any cleanup steps here, they will be run after each testcase */
47 }
48 
49 START_TEST(test_find_archetype_by_object_name) {
50  archetype *arch;
51 
52  arch = find_archetype_by_object_name("large city");
53  fail_unless(arch != NULL, "Searching for an existing arch name (large city) should work");
54  fail_unless(!strcmp(arch->clone.name, "large city"), "Searching for an existing arch name shoud have returned us large city but returned %s", arch->clone.name);
55  arch = find_archetype_by_object_name("Cloak of Magic Resistance");
56  fail_unless(arch != NULL, "Searching for an existing arch name (Cloak of Magic Resistance) should work");
57  fail_unless(!strcmp(arch->clone.name, "Cloak of Magic Resistance"), "Searching for an existing arch name shoud have returned us Cloak of Magic Resistance but returned %s", arch->clone.name);
58  arch = find_archetype_by_object_name("Cloak of Magic Resistanc");
59  fail_unless(arch == NULL, "Searching for an inexistant arch name (Cloak of Magic Resistanc) should return NULL");
60  arch = find_archetype_by_object_name("some really non existant archetype");
61  fail_unless(arch == NULL, "Searching for an inexistant arch name (some really non existant archetype) should return NULL");
63  fail_unless(arch == NULL, "Searching for empty arch name should return NULL");
64  arch = find_archetype_by_object_name(NULL);
65  fail_unless(arch == NULL, "Searching for NULL arch name should return NULL");
66 }
67 END_TEST
68 
69 START_TEST(test_find_archetype_by_object_type_name) {
70  archetype *arch;
71 
72  arch = find_archetype_by_object_type_name(66, "large city");
73  fail_unless(arch != NULL, "Searching for an existing arch name (large city) + type (66) should work");
74  fail_unless(arch->clone.type == 66, "Requested type 66 but got %d", arch->clone.type);
75  fail_unless(!strcmp(arch->clone.name, "large city"), "Searching for an existing arch name shoud have returned us large city but returned %s", arch->clone.name);
76  arch = find_archetype_by_object_type_name(87, "Cloak of Magic Resistance");
77  fail_unless(arch != NULL, "Searching for an existing arch name (Cloak of Magic Resistance) + type (87) should work");
78  fail_unless(arch->clone.type == 87, "Requested type 87 but got %d", arch->clone.type);
79  fail_unless(!strcmp(arch->clone.name, "Cloak of Magic Resistance"), "Searching for an existing arch name shoud have returned us Cloak of Magic Resistance but returned %s", arch->clone.name);
80  arch = find_archetype_by_object_type_name(87, "Cloak of Magic Resistanc");
81  fail_unless(arch == NULL, "Searching for an inexistant arch name (Cloak of Magic Resistanc) should return NULL");
82  arch = find_archetype_by_object_type_name(88, "Cloak of Magic Resistance");
83  fail_unless(arch == NULL, "Searching for an existing arch name (Cloak of Magic Resistance) but with wrong type (88) should return NULL");
84 }
85 END_TEST
86 
87 
88 START_TEST(test_get_archetype_by_skill_name) {
89  archetype *arch;
90 
91  arch = get_archetype_by_skill_name("alchemy", SKILL);
92  fail_unless(arch != NULL, "Should be able to discover the alchemy skill");
93  fail_unless(!strcmp(arch->name, "skill_alchemy"), "should have returned skill_alchemy but returned %s", arch->name);
94  arch = get_archetype_by_skill_name("alchemy", SKILLSCROLL);
95  fail_unless(arch != NULL, "Should be able to discover the scroll of alchemy skill or something similar");
96  arch = get_archetype_by_skill_name("one handed weapons", -1);
97  fail_unless(arch != NULL, "Should be able to discover something related to the 'one handed weapons' skill");
98  arch = get_archetype_by_skill_name(NULL, -1);
99  fail_unless(arch == NULL, "Asking for null skill should return null");
100 }
101 END_TEST
102 
103 START_TEST(test_get_archetype_by_type_subtype) {
104  archetype *arch;
105 
107  fail_unless(arch != NULL, "Should be able to find an arch of type SKILL, subtype SK_LITERACY");
108  fail_unless(arch->clone.type == SKILL, "Arch of type SKILL, subtype SK_LITERACY shoud have type %d but has type %d", SKILL, arch->clone.type);
109  fail_unless(arch->clone.subtype == SK_LITERACY, "Arch of type SKILL, subtype SK_LITERACY shoud have subtype %d but has subtype %d", SK_LITERACY, arch->clone.subtype);
110  fail_unless(arch != NULL, "Should be able to find an arch of type quest, subtype SK_LITERACY");
112  fail_unless(arch != NULL, "Should be able to find an arch of type SKILL, no subtype");
113  fail_unless(arch->clone.type == SKILL, "arch of type SKILL, no subtype should have type %d but has %d", SKILL, arch->clone.type);
115  fail_unless(arch != NULL, "Should be able to find an arch of type unknown, SK_LITERACY");
116  fail_unless(arch->clone.subtype == SK_LITERACY, "arch of type unknown, subtype quest in progress shoud have subtype %d but has subtype %d", SK_LITERACY, arch->clone.subtype);
117  arch = get_archetype_by_type_subtype(-1, -1);
118  fail_unless(arch != NULL, "Should be able to find arch of type unknown, subtype unknown, despite this being useless");
120  if (arch != NULL)
121  fail("Should be not able to find arch of inexistant type but got %p (%s)", arch, arch->name);
122 }
123 END_TEST
124 
125 
126 START_TEST(test_create_archetype_by_object_name) {
127  object *ob;
128 
129  ob = create_archetype_by_object_name("writing pen");
130  fail_unless(ob != NULL, "Should never return null");
131  fail_unless(strncmp(ob->name, ARCH_SINGULARITY, strlen(ARCH_SINGULARITY)), "Searching for writing pen should NOT have returned a singularity");
132  fail_unless(!strncmp(ob->name, "writing pen", strlen(ob->name)), "Searching for writing pen should have returned something with same base name but returned '%s'", ob->name);
133  ob = create_archetype_by_object_name("writing pen of hell raiser +3");
134  fail_unless(ob != NULL, "Should never return null");
135  fail_unless(strncmp(ob->name, ARCH_SINGULARITY, strlen(ARCH_SINGULARITY)), "Searching for writing pen of hell raiser +3 should NOT have returned a singularity");
136  fail_unless(!strncmp(ob->name, "writing pen of hell raiser +3", strlen(ob->name)), "Searching for writing pen of hell raiser +3 should have returned something with same base name but returned %s", ob->name);
138  fail_unless(ob != NULL, "Inexistent item shuold return a singularity");
139  fail_unless(!strncmp(ob->name, ARCH_SINGULARITY, strlen(ARCH_SINGULARITY)), "Searching for %* should have returned a singularity");
141  fail_unless(ob != NULL, "Inexistent item shuold return a singularity");
142  fail_unless(!strncmp(ob->name, ARCH_SINGULARITY, strlen(ARCH_SINGULARITY)), "Searching for \"\" should have returned a singularity");
143 }
144 END_TEST
145 
146 START_TEST(test_init_archetypes) {
147  /*init_archetypes is used by setup, just check it created the empty_archetype*/
148  archetype *arch = find_archetype("empty_archetype");
149 
150  fail_unless(arch != NULL, "init_archetype should have an 'empty_archetype' loaded");
151 }
152 END_TEST
153 
154 START_TEST(test_clear_archetable) {
155  clear_archetable(); /*should just not fail :p*/
156 }
157 END_TEST
158 
159 START_TEST(test_free_all_archs) {
160  archetype *arch;
161 
162  free_all_archs();
163  arch = find_archetype("empty_archetype");
164  fail_unless(arch == NULL, "init_archetype should not have an 'empty_archetype' loaded after call to free_all_archs");
165  init_archetypes();
166  arch = find_archetype("empty_archetype");
167  fail_unless(arch != NULL, "init_archetype should have an 'empty_archetype' loaded");
168 }
169 END_TEST
170 
171 START_TEST(test_get_archetype_struct) {
173 
174  fail_unless(arch != NULL, "get_archetype_struct should not return NULL");
175  fail_unless(arch->name == NULL, "arch->name of get_archetype_struct should be inited to NULL");
176  fail_unless(arch->head == NULL, "arch->head of get_archetype_struct should be inited to NULL");
177  fail_unless(arch->next == NULL, "arch->next of get_archetype_struct should be inited to NULL");
178  fail_unless(arch->more == NULL, "arch->more of get_archetype_struct should be inited to NULL");
179  fail_unless(arch->clone.other_arch == NULL, "arch->clone.other_arch of get_archetype_struct should be inited to NULL");
180  fail_unless(arch->clone.contr == NULL, "arch->clone.contr of get_archetype_struct should be inited to NULL");
181  fail_unless(arch->clone.next == NULL, "arch->clone.next of get_archetype_struct should be inited to NULL");
182  fail_unless(arch->clone.prev == NULL, "arch->clone.prev of get_archetype_struct should be inited to NULL");
183  fail_unless(arch->clone.active_next == NULL, "arch->clone.active_next of get_archetype_struct should be inited to NULL");
184  fail_unless(arch->clone.active_prev == NULL, "arch->clone.active_prev of get_archetype_struct should be inited to NULL");
185  fail_unless(arch->clone.below == NULL, "arch->clone.below of get_archetype_struct should be inited to NULL");
186  fail_unless(arch->clone.above == NULL, "arch->clone.above of get_archetype_struct should be inited to NULL");
187  fail_unless(arch->clone.inv == NULL, "arch->clone.inv of get_archetype_struct should be inited to NULL");
188  fail_unless(arch->clone.container == NULL, "arch->clone.container of get_archetype_struct should be inited to NULL");
189  fail_unless(arch->clone.env == NULL, "arch->clone.env of get_archetype_struct should be inited to NULL");
190  fail_unless(arch->clone.more == NULL, "arch->clone.more of get_archetype_struct should be inited to NULL");
191  fail_unless(arch->clone.head == NULL, "arch->clone.head of get_archetype_struct should be inited to NULL");
192  fail_unless(arch->clone.map == NULL, "arch->clone.map of get_archetype_struct should be inited to NULL");
193 
194  fail_unless(arch->clone.name == NULL, "arch->clone.name of get_archetype_struct should be inited to NULL");
195  fail_unless(arch->clone.name_pl == NULL, "arch->clone.name_pl of get_archetype_struct should be inited to NULL");
196  fail_unless(arch->clone.title == NULL, "arch->clone.title of get_archetype_struct should be inited to NULL");
197  fail_unless(arch->clone.race == NULL, "arch->clone.race of get_archetype_struct should be inited to NULL");
198  fail_unless(arch->clone.slaying == NULL, "arch->clone.slaying of get_archetype_struct should be inited to NULL");
199  fail_unless(arch->clone.msg == NULL, "arch->clone.msg of get_archetype_struct should be inited to NULL");
200  fail_unless(arch->clone.skill == NULL, "arch->clone.skill of get_archetype_struct should be inited to NULL");
201  fail_unless(arch->clone.lore == NULL, "arch->clone.lore of get_archetype_struct should be inited to NULL");
202 
203  fail_unless(arch->clone.current_weapon == NULL, "arch->clone.current_weapon of get_archetype_struct should be inited to NULL");
204  fail_unless(arch->clone.enemy == NULL, "arch->clone.enemy of get_archetype_struct should be inited to NULL");
205  fail_unless(arch->clone.attacked_by == NULL, "arch->clone.attacked_by of get_archetype_struct should be inited to NULL");
206  fail_unless(arch->clone.randomitems == NULL, "arch->clone.randomitems of get_archetype_struct should be inited to NULL");
207  fail_unless(arch->clone.chosen_skill == NULL, "arch->clone.chosen_skill of get_archetype_struct should be inited to NULL");
208  fail_unless(arch->clone.spellitem == NULL, "arch->clone.spellitem of get_archetype_struct should be inited to NULL");
209  fail_unless(arch->clone.spell == NULL, "arch->clone.spell of get_archetype_struct should be inited to NULL");
210  fail_unless(arch->clone.spellarg == NULL, "arch->clone.spellarg of get_archetype_struct should be inited to NULL");
211  fail_unless(arch->clone.arch == arch, "arch->clone.arch of get_archetype_struct should be inited to arch");
212  fail_unless(arch->clone.other_arch == NULL, "arch->clone.other_arch of get_archetype_struct should be inited to NULL");
213  fail_unless(arch->clone.custom_name == NULL, "arch->clone.custom_name of get_archetype_struct should be inited to NULL");
214  fail_unless(arch->clone.key_values == NULL, "arch->clone.key_values of get_archetype_struct should be inited to NULL");
215 }
216 END_TEST
217 
218 START_TEST(test_arch_to_object) {
219  archetype *arch;
220  object *obj;
221 
222  arch = find_archetype("empty_archetype");
223  obj = arch_to_object(arch);
224  fail_unless(obj != NULL, "instanciating an arch should not return null");
225 }
226 END_TEST
227 
228 START_TEST(test_create_singularity) {
229  object *obj;
230 
231  obj = create_singularity("XYZABCD");
232  fail_unless(obj != NULL, "create_singularity should not return null");
233  fail_unless(strstr(obj->name, "XYZABCD") != NULL, "create_singularity(\"XYZABCD\") should put XYZABCD somewhere in singularity name");
234 }
235 END_TEST
236 
237 START_TEST(test_create_archetype) {
238  object *obj;
239 
240  obj = create_archetype("empty_archetype");
241  fail_unless(obj != NULL, "create_archetype(\"empty_archetype\") should not return null");
242 }
243 END_TEST
244 
245 START_TEST(test_find_archetype) {
246  archetype *arch;
247 
248  arch = find_archetype("empty_archetype");
249  fail_unless(arch != NULL, "find_archetype(\"empty_archetype\") should not return null");
250  arch = find_archetype("elvenboots");
251  fail_unless(arch != NULL, "find_archetype(\"elvenboots\") should not return null");
252  arch = find_archetype("AA1234567890");
253  fail_unless(arch == NULL, "find_archetype(\"AA1234567890\") should return null");
254 }
255 END_TEST
256 
257 START_TEST(test_object_create_arch) {
258  archetype *arch;
259  object *obj;
260 
261  arch = find_archetype("dark_palace_4");
262  obj = object_create_arch(arch);
263  fail_unless(obj != NULL, "Should be able to fully instanciate the dark_palace");
264  fail_unless(obj->head == NULL, "The object is full, so we should have got it's head. So head should be null but was %p for object %p", obj->head, obj);
265  fail_unless(obj->more != NULL, "The object is full and multisquare, so more should not return null");
266 }
267 END_TEST
268 
269 static Suite *arch_suite(void) {
270  Suite *s = suite_create("arch");
271  TCase *tc_core = tcase_create("Core");
272 
273  /*setup and teardown will be called before each test in testcase 'tc_core' */
274  tcase_add_checked_fixture(tc_core, setup, teardown);
275 
276  suite_add_tcase(s, tc_core);
277  tcase_add_test(tc_core, test_find_archetype_by_object_name);
278  tcase_add_test(tc_core, test_find_archetype_by_object_type_name);
279  tcase_add_test(tc_core, test_get_archetype_by_skill_name);
280  tcase_add_test(tc_core, test_get_archetype_by_type_subtype);
281  tcase_add_test(tc_core, test_create_archetype_by_object_name);
282  tcase_add_test(tc_core, test_init_archetypes);
283  tcase_add_test(tc_core, test_clear_archetable);
284  tcase_add_test(tc_core, test_free_all_archs);
285  tcase_add_test(tc_core, test_get_archetype_struct);
286  tcase_add_test(tc_core, test_arch_to_object);
287  tcase_add_test(tc_core, test_create_singularity);
288  tcase_add_test(tc_core, test_create_archetype);
289  tcase_add_test(tc_core, test_find_archetype);
290  tcase_add_test(tc_core, test_object_create_arch);
291 
292  return s;
293 }
294 
295 int main(void) {
296  int nf;
297  Suite *s = arch_suite();
298  SRunner *sr = srunner_create(s);
299 
300  srunner_set_xml(sr, LOGDIR "/unit/common/arch.xml");
301  srunner_set_log(sr, LOGDIR "/unit/common/arch.out");
302  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
303  nf = srunner_ntests_failed(sr);
304  srunner_free(sr);
305  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
306 }
Main Crossfire structure, one ingame object.
Definition: object.h:274
#define ARCH_SINGULARITY
Archetype for singularity.
Definition: object.h:576
archetype * find_archetype(const char *name)
Finds, using the hashtable, which archetype matches the given name.
Definition: arch.c:695
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
START_TEST(test_find_archetype_by_object_name)
Definition: check_arch.c:49
static void teardown(void)
Definition: check_arch.c:45
void cctk_setdatadir(const char *datadir)
struct obj * container
Current container being used.
Definition: object.h:291
object * create_singularity(const char *name)
Creates a dummy object.
Definition: arch.c:598
Update if you add new types.
Definition: object.h:250
struct treasureliststruct * randomitems
Items to be generated.
Definition: object.h:385
object clone
An object from which to do object_copy()
Definition: object.h:470
struct obj * prev
Pointer to the previous object in the free/used list.
Definition: object.h:278
const char * slaying
Which race to do double damage to.
Definition: object.h:319
void init_archetypes(void)
Initialises the internal linked list of archetypes (read from file).
Definition: arch.c:182
uint8_t subtype
Subtype of object.
Definition: object.h:339
struct obj * above
Pointer to the object stacked above this one.
Definition: object.h:288
object * create_archetype_by_object_name(const char *name)
Creates an object given the name that appears during the game (for example, "writing pen" instead of ...
Definition: arch.c:160
Global type definitions and header inclusions.
struct obj * enemy
Monster/player to follow even if not closest.
Definition: object.h:381
struct archt * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:413
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:465
archetype * find_archetype_by_object_type_name(int type, const char *name)
This function retrieves an archetype by type and name that appears during the game.
Definition: arch.c:83
const char * lore
Obscure information about this object, to get put into books and the like.
Definition: object.h:323
struct obj * chosen_skill
The skill chosen to use.
Definition: object.h:386
const char * title
Of foo, etc.
Definition: object.h:317
void clear_archetable(void)
Initialise the hashtable used by the archetypes.
Definition: arch.c:205
struct obj * spell
Spell that was being cast.
Definition: object.h:408
const char * name_pl
The plural name of the object.
Definition: object.h:315
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
Definition: arch.c:620
Defines for loader.l / loader.c.
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
struct obj * active_prev
Previous object in the &#39;active list This is used in process_events so that the entire object list doe...
Definition: object.h:283
archetype * get_archetype_by_skill_name(const char *skill, int type)
Retrieves an archetype by skill name and type.
Definition: arch.c:107
const char * name
The name of the object, obviously...
Definition: object.h:311
struct obj * env
Pointer to the object which is the environment.
Definition: object.h:293
struct obj * below
Pointer to the object stacked below this one.
Definition: object.h:287
struct archt * more
Next part of a linked object.
Definition: object.h:469
archetype * find_archetype_by_object_name(const char *name)
This function retrieves an archetype given the name that appears during the game (for example...
Definition: arch.c:57
struct obj * current_weapon
Pointer to the weapon currently used.
Definition: object.h:370
struct archt * head
The main part of a linked object.
Definition: object.h:468
void cctk_setlog(const char *logfile)
set the logdir to use
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
static END_TEST Suite * arch_suite(void)
Definition: check_arch.c:269
char * spellarg
Optional argument when casting obj::spell.
Definition: object.h:409
static void setup(void)
Definition: check_arch.c:39
struct obj * active_next
Next object in the &#39;active&#39; list This is used in process_events so that the entire object list does n...
Definition: object.h:279
object * object_create_arch(archetype *at)
Create a full object using the given archetype.
Definition: arch.c:736
Literacy.
Definition: skills.h:27
can add a skill to player&#39;s inventory -bt.
Definition: object.h:234
void free_all_archs(void)
Frees all memory allocated to archetypes.
Definition: arch.c:287
const char * skill
Name of the skill this object uses/grants.
Definition: object.h:321
key_value * key_values
Fields not explictly known by the loader.
Definition: object.h:433
struct obj * next
Pointer to the next object in the free/used list.
Definition: object.h:277
struct obj * spellitem
Spell ability monster is choosing to use.
Definition: object.h:394
Also see SKILL_TOOL (74) below.
Definition: object.h:143
const char * custom_name
Custom name assigned by player.
Definition: object.h:432
archetype * get_archetype_by_type_subtype(int type, int subtype)
Retrieves an archetype by type and subtype.
Definition: arch.c:136
struct archt * arch
Pointer to archetype.
Definition: object.h:412
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct archt * next
Next archetype in a linked list.
Definition: object.h:467
const char * msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:322
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
struct obj * head
Points to the main object of a large body.
Definition: object.h:296
void cctk_init_std_archetypes(void)
Loads up to archetype initialisation using standard crossfire files in source tree.
int main(void)
Definition: check_arch.c:295
struct obj * more
Pointer to the rest of a large body of objects.
Definition: object.h:295
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
Definition: arch.c:571
archetype * get_archetype_struct(void)
Allocates, initialises and returns the pointer to an archetype structure.
Definition: arch.c:312
const char * name
More definite name, like "generate_kobold".
Definition: object.h:466
struct obj * attacked_by
This object start to attack us! only player & monster.
Definition: object.h:382