Crossfire Server, Branch 1.12  R12190
check_object.c
Go to the documentation of this file.
00001 /*
00002  * static char *rcsid_check_object_c =
00003  *   "$Id: check_object.c 11578 2009-02-23 22:02:27Z lalo $";
00004  */
00005 
00006 /*
00007  * CrossFire, A Multiplayer game for X-windows
00008  *
00009  * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
00010  * Copyright (C) 1992 Frank Tore Johansen
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025  *
00026  * The authors can be reached via e-mail at crossfire-devel@real-time.com
00027  */
00028 
00029 /*
00030  * This is the unit tests file for common/object.c
00031  */
00032 
00033 #include <global.h>
00034 #include <stdlib.h>
00035 #include <check.h>
00036 #include <loader.h>
00037 #include <toolkit_common.h>
00038 
00039 #include "stringbuffer.h"
00040 
00041 void setup(void) {
00042     cctk_setdatadir(BUILD_ROOT "lib");
00043     cctk_setlog(LOGDIR "/unit/common/object.out");
00044     printf("set log to %s\n", LOGDIR"/unit/common/object.out");
00045     cctk_init_std_archetypes();
00046 }
00047 
00048 void teardown(void) {
00049     /* put any cleanup steps here, they will be run after each testcase */
00050 }
00051 
00052 /*
00053  * Things to check
00054  * update_turn_face
00055  * update_ob_speed
00056  * remove_from_active_list
00057  * update_object
00058  * free_object
00059  * count_free
00060  * count_used
00061  * count_active
00062  * sub_weight
00063  * remove_ob
00064  * merge_ob
00065  * insert_ob_in_map_at
00066  * insert_ob_in_map
00067  * replace_insert_ob_in_map
00068  * get_split_ob
00069  * decrease_ob_nr
00070  * add_weight
00071  * insert_ob_in_ob
00072  * check_move_on
00073  * present_arch
00074  * present
00075  * present_in_ob
00076  * present_in_ob_by_name
00077  * present_arch_in_ob
00078  * flag_inv
00079  * unflag_inv
00080  * set_cheat
00081  * find_free_spot
00082  * find_first_free_spot
00083  * get_search_arr
00084  * find_dir
00085  * distance
00086  * find_dir_2
00087  * absdir
00088  * dirdiff
00089  * can_see_monsterP
00090  * can_pick
00091  * object_create_clone
00092  * was_destroyed
00093  * find_obj_by_type_subtype
00094  * get_ob_key_link
00095  * get_ob_key_value
00096  * set_ob_key_value
00097  * item_matched_string
00098  */
00102 START_TEST(test_can_merge) {
00103     object *ob1;
00104     object *ob2;
00105 
00106     ob1 = cctk_create_game_object(NULL);
00107     ob2 = cctk_create_game_object(NULL);
00108     fail_unless(can_merge(ob1, ob2), "Should be able to merge 2 same object");
00109     ob2->name = add_string("Not same name");
00110     fail_unless(!can_merge(ob1, ob2), "Should not be able to merge 2 object with different names");
00111     ob2 = cctk_create_game_object(NULL);
00112     ob2->type++;
00113     fail_unless(!can_merge(ob1, ob2), "Should not be able to merge 2 object with different types");
00114     ob2 = cctk_create_game_object(NULL);
00115     ob1->nrof = (1UL<<31)-1;
00116     ob2->nrof = 1;
00117     fail_unless(!can_merge(ob1, ob2), "Should not be able to merge 2 object if result nrof goes to 1<<31 or higher");
00118     /*TESTME*/
00119 }
00120 END_TEST
00121 
00125 START_TEST(test_sum_weight) {
00126     object *ob1;
00127     object *ob2;
00128     object *ob3;
00129     object *ob4;
00130     unsigned long sum;
00131 
00132     ob1 = cctk_create_game_object(NULL);
00133     ob2 = cctk_create_game_object(NULL);
00134     ob3 = cctk_create_game_object(NULL);
00135     ob4 = cctk_create_game_object(NULL);
00136     ob1->weight = 10; /*This should not be taken into account by sum_weight*/
00137     ob1->type = CONTAINER;
00138     ob1->stats.Str = 40; /*40% reduction of weight*/
00139     ob2->weight = 6;
00140     ob2->nrof = 10;
00141     ob3->weight = 7;
00142     ob4->weight = 8;
00143     insert_ob_in_ob(ob2, ob1);
00144     insert_ob_in_ob(ob3, ob1);
00145     insert_ob_in_ob(ob4, ob1);
00146     sum = sum_weight(ob1);
00147     fail_unless(sum == 45, "Sum of object's inventory should be 45 ((6*10+7+8)*.6) but was %lu.", sum);
00148 }
00149 END_TEST
00150 
00154 START_TEST(test_object_get_env_recursive) {
00155     object *ob1;
00156     object *ob2;
00157     object *ob3;
00158     object *ob4;
00159     object *result;
00160 
00161     ob1 = cctk_create_game_object(NULL);
00162     ob2 = cctk_create_game_object(NULL);
00163     ob3 = cctk_create_game_object(NULL);
00164     ob4 = cctk_create_game_object(NULL);
00165     insert_ob_in_ob(ob2, ob1);
00166     insert_ob_in_ob(ob3, ob2);
00167     insert_ob_in_ob(ob4, ob3);
00168     result = object_get_env_recursive(ob4);
00169     fail_unless(result == ob1, "Getting top level container for ob4(%p) should bring ob1(%p) but brought %p.", ob4, ob1, result);
00170 }
00171 END_TEST
00172 
00176 START_TEST(test_get_player_container) {
00177     object *ob1;
00178     object *ob2;
00179     object *ob3;
00180     object *ob4;
00181     object *result;
00182 
00183     ob1 = cctk_create_game_object(NULL);
00184     ob2 = cctk_create_game_object(NULL);
00185     ob3 = cctk_create_game_object(NULL);
00186     ob4 = cctk_create_game_object(NULL);
00187     insert_ob_in_ob(ob2, ob1);
00188     insert_ob_in_ob(ob3, ob2);
00189     insert_ob_in_ob(ob4, ob3);
00190     result = get_player_container(ob4);
00191     fail_unless(result == NULL, "Getting containing player for ob4(%p) should bring NULL but brought %p while not contained in a player.", ob4, result);
00192     ob1->type = PLAYER;
00193     result = get_player_container(ob4);
00194     fail_unless(result == ob1, "Getting containing player for ob4(%p) should bring ob1(%p) but brought %p while ob1 is player.", ob4, ob1, result);
00195 }
00196 END_TEST
00197 
00201 START_TEST(test_dump_object) {
00202     object *ob1;
00203     object *ob2;
00204     object *ob3;
00205     StringBuffer *sb;
00206     char *result;
00207 
00208     ob1 = cctk_create_game_object(NULL);
00209     ob2 = cctk_create_game_object(NULL);
00210     ob3 = cctk_create_game_object(NULL);
00211     insert_ob_in_ob(ob2, ob1);
00212     insert_ob_in_ob(ob3, ob2);
00213     sb = stringbuffer_new();
00214     dump_object(ob1, sb);
00215     result = stringbuffer_finish(sb);
00216     fail_unless(strstr(result, "arch") != NULL, "The object dump should contain 'arch' but was %s", sb);
00217     free(result);
00218 }
00219 END_TEST
00220 
00224 START_TEST(test_dump_all_objects) {
00225     object *ob1;
00226     object *ob2;
00227     object *ob3;
00228 
00229     ob1 = cctk_create_game_object(NULL);
00230     ob2 = cctk_create_game_object(NULL);
00231     ob3 = cctk_create_game_object(NULL);
00232     dump_all_objects(); /*Should not crash, that all i can test*/
00233 }
00234 END_TEST
00235 
00239 START_TEST(test_find_object) {
00240     object *ob1;
00241     object *result;
00242 
00243     ob1 = cctk_create_game_object(NULL);
00244     ob1 = cctk_create_game_object(NULL);
00245     ob1 = cctk_create_game_object(NULL);
00246     result = find_object(ob1->count);
00247     fail_unless(result == ob1, "Should find ob1(%p) while search for item %d but got %p", ob1, ob1->count, result);
00248 }
00249 END_TEST
00250 
00254 START_TEST(test_find_object_name) {
00255     object *ob1;
00256     object *result;
00257 
00258     ob1 = cctk_create_game_object(NULL);
00259     ob1->name = add_string("This is a name");
00260     ob1 = cctk_create_game_object(NULL);
00261     ob1->name = add_string("This is another name");
00262     ob1 = cctk_create_game_object(NULL);
00263     ob1->name = add_string("This is the key name");
00264     result = find_object_name(add_string("This is the key name"));
00265     fail_unless(result == ob1, "Searching for object with name 'This is the key name' returned %p(%s) instead of ob1(%p)", result, result ? result->name : "null", ob1);
00266 }
00267 END_TEST
00268 
00272 START_TEST(test_free_all_object_data) {
00273   /*TESTME*/
00274 }
00275 END_TEST
00276 
00280 START_TEST(test_get_owner) {
00281     object *ob1;
00282     object *ob2;
00283 
00284     ob1 = cctk_create_game_object(NULL);
00285     ob2 = cctk_create_game_object(NULL);
00286     set_owner(ob2, ob1);
00287     CLEAR_FLAG(ob1, FLAG_REMOVED);
00288     CLEAR_FLAG(ob2, FLAG_REMOVED);
00289     fail_unless(get_owner(ob2) == ob1, "Owner of ob2(%p) shoud be ob1(%p) but was %p", ob2, ob1, get_owner(ob2));
00290 }
00291 END_TEST
00292 
00296 START_TEST(test_clear_owner) {
00297     object *ob1;
00298     object *ob2;
00299 
00300     ob1 = cctk_create_game_object(NULL);
00301     ob2 = cctk_create_game_object(NULL);
00302     set_owner(ob2, ob1);
00303     fail_unless(ob2->owner != NULL, "Prior to testing clear_owner, owner of ob2 was wrongly initialized");
00304     clear_owner(ob2);
00305     fail_unless(ob2->owner == NULL, "After clear_owner ob2 still had an owner");
00306 }
00307 END_TEST
00308 
00312 START_TEST(test_set_owner) {
00313     object *ob1;
00314     object *ob2;
00315 
00316     ob1 = cctk_create_game_object(NULL);
00317     ob2 = cctk_create_game_object(NULL);
00318     set_owner(ob2, ob1);
00319     fail_unless(ob2->owner == ob1, "After set_owner ob2(%p) owner should be ob1(%p) but was (%p)", ob2, ob1, ob2->owner);
00320 }
00321 END_TEST
00322 
00326 START_TEST(test_copy_owner) {
00327     object *ob1;
00328     object *ob2;
00329     object *ob3;
00330 
00331     ob1 = cctk_create_game_object(NULL);
00332     ob2 = cctk_create_game_object(NULL);
00333     ob3 = cctk_create_game_object(NULL);
00334     set_owner(ob2, ob1);
00335     copy_owner(ob3, ob2);
00336     fail_unless(get_owner(ob2) == get_owner(ob3), "After copy_owner, ob3 and ob2 should have same owner (ob1=%p) but got %p and %p", get_owner(ob3), get_owner(ob2));
00337 }
00338 END_TEST
00339 
00343 START_TEST(test_reset_object) {
00344     object *ob1;
00345 
00346     ob1 = cctk_create_game_object(NULL);
00347     reset_object(ob1);
00348     fail_unless(ob1->name == NULL, "Field name of ob1 was not NULLified by reset_object");
00349     fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not NULLified by reset_object");
00350     fail_unless(ob1->title == NULL, "Field title of ob1 was not NULLified by reset_object");
00351     fail_unless(ob1->race == NULL, "Field race of ob1 was not NULLified by reset_object");
00352     fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not NULLified by reset_object");
00353     fail_unless(ob1->skill == NULL, "Field skill of ob1 was not NULLified by reset_object");
00354     fail_unless(ob1->msg == NULL, "Field msg of ob1 was not NULLified by reset_object");
00355     fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not NULLified by reset_object");
00356     fail_unless(ob1->lore == NULL, "Field lore of ob1 was not NULLified by reset_object");
00357 }
00358 END_TEST
00359 
00363 START_TEST(test_clear_object) {
00364     object *ob1;
00365     const char *reference;
00366 
00367     ob1 = cctk_create_game_object(NULL);
00368     cctk_set_object_strings(ob1, "This is a test String");
00369     reference = add_string("This is a test String");
00370     clear_object(ob1);
00371     fail_unless(ob1->name == NULL, "Field name of ob1 was not cleaned by clear_object");
00372     fail_unless(ob1->name_pl == NULL, "Field name_pl of ob1 was not cleaned by clear_object");
00373     fail_unless(ob1->title == NULL, "Field title of ob1 was not cleaned by clear_object");
00374     fail_unless(ob1->race == NULL, "Field race of ob1 was not cleaned by clear_object");
00375     fail_unless(ob1->slaying == NULL, "Field slaying of ob1 was not cleaned by clear_object");
00376     fail_unless(ob1->skill == NULL, "Field skill of ob1 was not cleaned by clear_object");
00377     fail_unless(ob1->msg == NULL, "Field msg of ob1 was not cleaned by clear_object");
00378     fail_unless(ob1->materialname == NULL, "Field materialname of ob1 was not cleaned by clear_object");
00379     fail_unless(ob1->lore == NULL, "Field lore of ob1 was not cleaned by clear_object");
00380     fail_unless(query_refcount(reference) == 1, "The number of references to string should drop back to 1 but was %d", query_refcount(reference));
00381 }
00382 END_TEST
00383 
00387 START_TEST(test_copy_object) {
00388     object *ob1;
00389     object *ob2;
00390     const char *reference;
00391 
00392     ob1 = cctk_create_game_object(NULL);
00393     ob2 = cctk_create_game_object(NULL);
00394     cctk_set_object_strings(ob1, "test String1");
00395     cctk_set_object_strings(ob2, "test String2");
00396     reference = add_string("test String2");
00397     copy_object(ob1, ob2);
00398     fail_unless(ob1->name == ob2->name, "Field name of ob1 should match ob2");
00399     fail_unless(ob1->name_pl == ob2->name_pl, "Field name_pl of ob1 should match ob2");
00400     fail_unless(ob1->title == ob2->title, "Field title of ob1 should match ob2");
00401     fail_unless(ob1->race == ob2->race, "Field race of ob1 should match ob2");
00402     fail_unless(ob1->slaying == ob2->slaying, "Field slaying of ob1 should match ob2");
00403     fail_unless(ob1->skill == ob2->skill, "Field skill of ob1 should match ob2");
00404     fail_unless(ob1->msg == ob2->msg, "Field msg of ob1 should match ob2");
00405     fail_unless(ob1->materialname == ob2->materialname, "Field materialname of ob1 should match ob2");
00406     fail_unless(ob1->lore == ob2->lore, "Field lore of ob1 should match ob2");
00407     fail_unless(query_refcount(reference) == 1, "refcount of marker string is not dropped to 1 after copy object, some string field were not cleaned. refcount: %d", query_refcount(reference));
00408 }
00409 END_TEST
00410 
00415 START_TEST(test_get_object) {
00416     object *ob;
00417     long int i;
00418 
00419     ob = get_object();
00420     fail_unless(ob != NULL, "Should get an object after calling get_object()");
00421     fail_unless(ob->name == NULL, "Field name has not been nullified by get_object()");
00422     fail_unless(ob->name_pl == NULL, "Field name_pl has not been nullified by get_object()");
00423     fail_unless(ob->title == NULL, "Field title has not been nullified by get_object()");
00424     fail_unless(ob->race == NULL, "Field race has not been nullified by get_object()");
00425     fail_unless(ob->slaying == NULL, "Field slaying has not been nullified by get_object()");
00426     fail_unless(ob->skill == NULL, "Field skill has not been nullified by get_object()");
00427     fail_unless(ob->lore == NULL, "Field lore has not been nullified by get_object()");
00428     fail_unless(ob->msg == NULL, "Field msg has not been nullified by get_object()");
00429     fail_unless(ob->materialname == NULL, "Field materialname has not been nullified by get_object()");
00430     fail_unless(ob->prev == NULL, "Field prev has not been nullified by get_object()");
00431     fail_unless(ob->active_next == NULL, "Field active_next has not been nullified by get_object()");
00432     fail_unless(ob->active_prev == NULL, "Field active_prev has not been nullified by get_object()");
00433     /* did you really thing i'll go with only one object? */
00434     /* let's go for about 2M allocations in a row, let's test roughness */
00435     for (i = 0; i < 1U<<17; i++) {
00436         ob = get_object();
00437         fail_unless(ob != NULL, "Should get an object after calling get_object() (iteration %l)", i);
00438         if (!(i&((1<<13)-1)))
00439             LOG(llevDebug, "%ldk items created with get_object\n", i>>10);
00440     }
00441 }
00442 END_TEST
00443 
00447 START_TEST(test_update_turn_face) {
00448     object *ob1;
00449     New_Face *face1;
00450     New_Face *face2;
00451 
00452     ob1 = cctk_create_game_object("xan");
00453     ob1->direction = 1;
00454     update_turn_face(ob1);
00455     face1 = ob1->face;
00456     ob1->direction = 0;
00457     update_turn_face(ob1);
00458     face2 = ob1->face;
00459     fail_unless(face2 != face1, "2 opposite direction should provide different faces after update_turn_face");
00460 }
00461 END_TEST
00462 
00463 #define IS_OBJECT_ACTIVE(op) (op->active_next || op->active_prev || op == active_objects)
00464 
00467 START_TEST(test_update_ob_speed) {
00468     object *ob1;
00469     object *ob2;
00470     object *ob3;
00471     object *ob4;
00472 
00473     ob1 = cctk_create_game_object(NULL);
00474     ob2 = cctk_create_game_object(NULL);
00475     ob3 = cctk_create_game_object(NULL);
00476     ob4 = cctk_create_game_object(NULL);
00477     ob1->speed = MIN_ACTIVE_SPEED;
00478     update_ob_speed(ob1);
00479     fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed <=MIN_ACTIVE_SPEED(%f) should not be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
00480     ob1->speed = -MIN_ACTIVE_SPEED;
00481     update_ob_speed(ob1);
00482     fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed <=MIN_ACTIVE_SPEED(%f) should not be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
00483     ob1->speed = MIN_ACTIVE_SPEED*2;
00484     update_ob_speed(ob1);
00485     fail_unless(IS_OBJECT_ACTIVE(ob1), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
00486     ob2->speed = -MIN_ACTIVE_SPEED*2;
00487     update_ob_speed(ob2);
00488     fail_unless(IS_OBJECT_ACTIVE(ob2), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob2->speed);
00489     ob4->speed = ob3->speed = ob2->speed;
00490     update_ob_speed(ob3);
00491     update_ob_speed(ob4);
00492     fail_unless(IS_OBJECT_ACTIVE(ob3), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob3->speed);
00493     fail_unless(IS_OBJECT_ACTIVE(ob4), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob4->speed);
00494     ob1->speed = 0.0;
00495     ob2->speed = 0.0;
00496     ob3->speed = 0.0;
00497     ob4->speed = 0.0;
00498     update_ob_speed(ob1);
00499     update_ob_speed(ob2);
00500     update_ob_speed(ob3);
00501     update_ob_speed(ob4);
00502     fail_unless(!IS_OBJECT_ACTIVE(ob1), "Object with absolute speed 0.0 should be inactivated", ob1->speed);
00503     fail_unless(!IS_OBJECT_ACTIVE(ob2), "Object with absolute speed 0.0 should be inactivated", ob2->speed);
00504     fail_unless(!IS_OBJECT_ACTIVE(ob3), "Object with absolute speed 0.0 should be inactivated", ob3->speed);
00505     fail_unless(!IS_OBJECT_ACTIVE(ob4), "Object with absolute speed 0.0 should be inactivated", ob4->speed);
00506 }
00507 END_TEST
00508 
00512 START_TEST(test_remove_from_active_list) {
00513     object *ob1;
00514 
00515     ob1 = cctk_create_game_object(NULL);
00516     ob1->speed = MIN_ACTIVE_SPEED*2;
00517     update_ob_speed(ob1);
00518     fail_unless(IS_OBJECT_ACTIVE(ob1), "Object with absolute speed >MIN_ACTIVE_SPEED(%f) should be made active (speed=%f)", MIN_ACTIVE_SPEED, ob1->speed);
00519     remove_from_active_list(ob1);
00520     fail_unless(!IS_OBJECT_ACTIVE(ob1), "After call to remove_from_active_list, object should be made inactive");
00521 }
00522 END_TEST
00523 #undef IS_OBJECT_ACTIVE
00524 
00528 START_TEST(test_update_object) {
00529     /*TESTME (this one need a map loading, left for later*/
00530 }
00531 END_TEST
00532 
00536 START_TEST(test_free_object) {
00537     object *ob1;
00538     object *ob2;
00539 
00540     ob1 = cctk_create_game_object(NULL);
00541     ob2 = cctk_create_game_object(NULL);
00542     insert_ob_in_ob(ob2, ob1);
00543     free_object(ob1);
00544     fail_unless(QUERY_FLAG(ob1, FLAG_FREED), "Freeing ob1 should mark it freed");
00545     fail_unless(QUERY_FLAG(ob2, FLAG_FREED), "Freeing ob1 should mark it's content freed");
00546 }
00547 END_TEST
00548 
00552 START_TEST(test_count_free) {
00553     object *ob1;
00554     int free1, free2;
00555 
00556     ob1 = cctk_create_game_object(NULL);
00557     free1 = count_free();
00558     ob1 = cctk_create_game_object(NULL);
00559     free2 = count_free();
00560     /* Behaviour under MEMORY_DEBUG is to allocate each object separately so
00561      * both will be 0. Allow test suite to pass with this option.
00562      */
00563 #ifdef MEMORY_DEBUG
00564     fail_unless(((free2 == 0) && (free1 == 0)), "after creating an object, the count_free() should return 0 (compiled with MEMORY_DEBUG)", free1-1, free2);
00565 #else
00566     fail_unless((free2 == free1-1), "after creating an object, the count_free() should return one less (%d) but returned %d", free1-1, free2);
00567 #endif
00568 }
00569 END_TEST
00570 
00574 START_TEST(test_count_used) {
00575     object *ob1;
00576     int used1, used2;
00577 
00578     ob1 = cctk_create_game_object(NULL);
00579     used1 = count_used();
00580     ob1 = cctk_create_game_object(NULL);
00581     used2 = count_used();
00582     fail_unless((used2 == used1+1), "after creating an object, the count_used() should return one more (%d) but returned %d", used1-1, used2);
00583 }
00584 END_TEST
00585 
00589 START_TEST(test_count_active) {
00590     object *ob1;
00591     int active1, active2;
00592 
00593     ob1 = cctk_create_game_object(NULL);
00594     ob1->speed = MIN_ACTIVE_SPEED*2;
00595     update_ob_speed(ob1);
00596     active1 = count_active();
00597     ob1 = cctk_create_game_object(NULL);
00598     ob1->speed = MIN_ACTIVE_SPEED*2;
00599     update_ob_speed(ob1);
00600     active2 = count_active();
00601     fail_unless((active2 == active1+1), "after activating an additional object, count_active should return one less %d but returned %d", active1-1, active2);
00602 }
00603 END_TEST
00604 
00608 START_TEST(test_sub_weight) {
00609     object *ob1;
00610     object *ob2;
00611     object *ob3;
00612     object *ob4;
00613     unsigned long sum;
00614 
00615     ob1 = cctk_create_game_object(NULL);
00616     ob2 = cctk_create_game_object(NULL);
00617     ob3 = cctk_create_game_object(NULL);
00618     ob4 = cctk_create_game_object(NULL);
00619     ob1->weight = 10; /*This should not be taken into account by sum_weight*/
00620     ob1->type = CONTAINER;
00621     ob2->type = CONTAINER;
00622     ob3->type = CONTAINER;
00623     ob1->stats.Str = 40; /*40% reduction of weight*/
00624     ob2->weight = 10;
00625     ob3->weight = 10;
00626     ob4->weight = 10;
00627     insert_ob_in_ob(ob2, ob1);
00628     insert_ob_in_ob(ob3, ob2);
00629     insert_ob_in_ob(ob4, ob3);
00630     sum = sum_weight(ob1);
00631     fail_unless(sum == 18, "Sum of object's inventory should be 18 (30*0.6+10) but was %lu.", sum);
00632     sub_weight(ob4, 10);
00633     fail_unless(ob1->carrying == 12, "after call to sub_weight, carrying of ob1 should be 22 but was %d", ob1->carrying);
00634 }
00635 END_TEST
00636 
00640 START_TEST(test_remove_ob) {
00641     /*TESTME test those
00642      * ob with more
00643      * player inv
00644      * remove from map
00645      */
00646 }
00647 END_TEST
00648 
00652 START_TEST(test_merge_ob) {
00653     object *ob1;
00654     object *ob2;
00655     object *ob3;
00656     object *ob4;
00657     object *op;
00658 
00659     ob1 = cctk_create_game_object(NULL);
00660     ob2 = cctk_create_game_object(NULL);
00661     ob3 = cctk_create_game_object(NULL);
00662     ob4 = cctk_create_game_object(NULL);
00663     op = cctk_create_game_object(NULL);
00664     ob1->below = ob2;
00665     ob2->below = ob3;
00666     ob3->below = ob4;
00667     ob2->above = ob1;
00668     ob3->above = ob2;
00669     ob4->above = ob3;
00670     ob1->name = add_string("test");
00671     ob2->name = add_string("test2");
00672     ob3->name = add_string("test3");
00673 }
00674 END_TEST
00675 
00679 START_TEST(test_insert_ob_in_map_at) {
00680     mapstruct *map;
00681     object *first = NULL;
00682     object *got = NULL;
00683 
00684     map = get_empty_map(5, 5);
00685     fail_unless(map != NULL, "get_empty_map returned NULL.");
00686 
00687     /* Single tile object */
00688     first = cctk_create_game_object("barrel");
00689     fail_unless(first != NULL, "create barrel failed");
00690 
00691     got = insert_ob_in_map_at(first, map, NULL, 0, 0, 0);
00692     fail_unless(got == first, "item shouldn't be destroyed");
00693 
00694     first = cctk_create_game_object("dragon");
00695     fail_unless(first != NULL, "create dragon failed");
00696     fail_unless(first->more != NULL, "no other body part");
00697 
00698     got = insert_ob_in_map_at(first, map, NULL, 0, 1, 1);
00699     fail_unless(got == first, "item shouldn't be destroyed");
00700 
00701     fail_unless(GET_MAP_OB(map, 1, 1) == first, "item isn't on 1,1");
00702     fail_unless(GET_MAP_OB(map, 2, 1) != NULL, "no item on 2,1");
00703     fail_unless(GET_MAP_OB(map, 2, 1)->head == first, "head of 2,1 isn't 1,1");
00704 }
00705 END_TEST
00706 
00710 START_TEST(test_insert_ob_in_map) {
00711     mapstruct *map;
00712     object *first = NULL;
00713     object *second = NULL;
00714     object *third = NULL;
00715     object *floor = NULL;
00716     object *got = NULL;
00717 
00718     map = get_empty_map(5, 5);
00719     fail_unless(map != NULL, "get_empty_map returned NULL.");
00720 
00721     /* First, simple tests for insertion. */
00722     floor = cctk_create_game_object("woodfloor");
00723     fail_unless(floor != NULL, "create woodfloor failed");
00724     floor->x = 3;
00725     floor->y = 3;
00726 
00727     got = insert_ob_in_map(floor, map, NULL, 0);
00728     fail_unless(got == floor, "woodfloor shouldn't disappear");
00729     fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should be first object");
00730 
00731     first = cctk_create_game_object("barrel");
00732     fail_unless(first != NULL, "create barrel failed");
00733     first->x = 3;
00734     first->y = 3;
00735 
00736     got = insert_ob_in_map(first, map, NULL, 0);
00737     fail_unless(got == first, "barrel shouldn't disappear");
00738     fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
00739     fail_unless(floor->above == first, "barrel should be above floor");
00740 
00741     second = cctk_create_game_object("gem");
00742     fail_unless(second != NULL, "create gem failed");
00743     second->nrof = 1;
00744     second->x = 3;
00745     second->y = 3;
00746 
00747     got = insert_ob_in_map(second, map, NULL, INS_ABOVE_FLOOR_ONLY);
00748     fail_unless(got == second, "gem shouldn't disappear");
00749     fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
00750     fail_unless(floor->above == second, "gem should be above floor");
00751     fail_unless(second->above == first, "barrel should be above gem");
00752 
00753     third = cctk_create_game_object("bed_1");
00754     fail_unless(third != NULL, "create bed_1 failed");
00755     third->nrof = 1;
00756     third->x = 3;
00757     third->y = 3;
00758 
00759     got = insert_ob_in_map(third, map, first, INS_BELOW_ORIGINATOR);
00760     fail_unless(got == third, "bed_1 shouldn't disappear");
00761     fail_unless(floor == GET_MAP_OB(map, 3, 3), "woodfloor should still be first object");
00762     fail_unless(third->above == first, "bed should be below barrel");
00763     fail_unless(third->below == second, "bed should be above gem");
00764 
00765     /* Merging tests. */
00766     third = cctk_create_game_object("gem");
00767     fail_unless(third != NULL, "create gem failed");
00768     third->nrof = 1;
00769     third->x = 3;
00770     third->y = 3;
00771 
00772     got = insert_ob_in_map(third, map, NULL, 0);
00773     fail_unless(got == third, "gem shouldn't disappear");
00774     fail_unless(QUERY_FLAG(second, FLAG_FREED), "first gem should have been removed.");
00775     fail_unless(third->nrof == 2, "second gem should have nrof 2");
00776 
00777     second = cctk_create_game_object("gem");
00778     fail_unless(second != NULL, "create gem failed");
00779     second->nrof = 1;
00780     second->x = 3;
00781     second->y = 3;
00782     second->value = 1;
00783 
00784     got = insert_ob_in_map(second, map, NULL, 0);
00785     fail_unless(got == second, "modified gem shouldn't disappear");
00786     fail_unless(second->nrof == 1, "modified gem should have nrof 1");
00787 
00788     /* Now check sacrificing, on another spot.
00789      * Can't work here, as altar logic is in server.
00790      * -> move that there.
00791      */
00792 /*
00793     first = cctk_create_game_object("altar");
00794     fail_unless(first != NULL, "create altar failed");
00795     first->x = 2;
00796     first->y = 2;
00797     first->stats.food = 5;
00798     first->value = 0;
00799     fail_unless(insert_ob_in_map(first, map, NULL, 0) == first, "altar shouldn't disappear");
00800     fail_unless(GET_MAP_MOVE_ON(map, 2, 2)&MOVE_WALK == MOVE_WALK, "floor should have MOVE_WALK set");
00801 
00802     second = cctk_create_game_object("food");
00803     fail_unless(second != NULL, "create food failed");
00804     second->nrof = 5;
00805     second->x = 2;
00806     second->y = 2;
00807     got = insert_ob_in_map(second, map, NULL, 0);
00808     fail_unless(got == NULL, "insert_ob_in_map(food) should have returned NULL");
00809     fail_unless(QUERY_FLAG(second, FLAG_FREED), "food should have been freed");
00810 */
00811 }
00812 END_TEST
00813 
00814 
00818 START_TEST(test_replace_insert_ob_in_map) {
00819     mapstruct *map;
00820     object *first = NULL, *second = NULL, *third = NULL;
00821     tag_t tag_first, tag_second, tag_third;
00822     object *got = NULL;
00823 
00824     map = get_empty_map(5, 5);
00825     fail_unless(map != NULL, "get_empty_map returned NULL.");
00826 
00827     /* Single tile object */
00828     first = cctk_create_game_object("barrel");
00829     fail_unless(first != NULL, "create barrel failed");
00830     tag_first = first->count;
00831 
00832     got = insert_ob_in_map_at(first, map, NULL, 0, 0, 0);
00833     fail_unless(got == first, "item shouldn't be destroyed");
00834 
00835     second = cctk_create_game_object("table");
00836     fail_unless(second != NULL, "create table failed");
00837 
00838     got = insert_ob_in_map_at(second, map, NULL, 0, 0, 0);
00839     fail_unless(got == second, "second item shouldn't be destroyed");
00840     tag_second = second->count;
00841 
00842     third = cctk_create_game_object("barrel");
00843     fail_unless(third != NULL, "create 2nd barrel failed");
00844     got = insert_ob_in_map_at(third, map, NULL, 0, 0, 0);
00845     fail_unless(got == third, "second barrel shouldn't be destroyed");
00846     tag_third = third->count;
00847 
00848     fail_unless(GET_MAP_OB(map, 0, 0) == first, "item at 0,0 isn't barrel");
00849     fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "second item at 0,0 isn't table");
00850     fail_unless(GET_MAP_OB(map, 0, 0)->above->above == third, "third item at 0,0 isn't barrel");
00851 
00852     replace_insert_ob_in_map("barrel", second);
00853 
00854     fail_unless(GET_MAP_OB(map, 0, 0) != first, "item at 0, 0 is still first?");
00855     fail_unless(was_destroyed(first, tag_first), "1st barrel should be destroyed");
00856     fail_unless(!was_destroyed(second, tag_second), "table shouldn't be destroyed");
00857     fail_unless(was_destroyed(third, tag_third), "2nd barrel should be destroyed");
00858 
00859     fail_unless(GET_MAP_OB(map, 0, 0) != NULL, "no item at 0,0 after replace_insert_ob_in_map");
00860     fail_unless(GET_MAP_OB(map, 0, 0) != second, "second at bottom at 0,0 after replace_insert_ob_in_map");
00861     fail_unless(GET_MAP_OB(map, 0, 0)->above == second, "table isn't above new barrel");
00862     fail_unless(strcmp(GET_MAP_OB(map, 0, 0)->arch->name, "barrel") == 0, "item at 0,0 is not a barrel after replace_insert_ob_in_map");
00863 }
00864 END_TEST
00865 
00869 START_TEST(test_get_split_ob) {
00870     object *first = NULL;
00871     object *second = NULL;
00872     char err[50];
00873 
00874     first = cctk_create_game_object("gem");
00875     fail_unless(first != NULL, "create gem failed");
00876     first->nrof = 5;
00877 
00878     second = get_split_ob(first, 2, err, sizeof(err));
00879     fail_unless(second != NULL, "should return an item");
00880     fail_unless(second->nrof == 2, "2 expected to split");
00881     fail_unless(first->nrof == 3, "3 should be left");
00882 
00883     second = get_split_ob(first, 3, err, sizeof(err));
00884     fail_unless(second != NULL, "should return an item");
00885     fail_unless(QUERY_FLAG(first, FLAG_FREED), "first should be freed");
00886 
00887     first = get_split_ob(second, 10, err, sizeof(err));
00888     fail_unless(first == NULL, "should return NULL");
00889     fail_unless(second->nrof == 3, "3 should be left");
00890 }
00891 END_TEST
00892 
00896 START_TEST(test_decrease_ob_nr) {
00897     object *first = NULL;
00898     object *second = NULL;
00899 
00900     first = cctk_create_game_object("gem");
00901     fail_unless(first != NULL, "create gem failed");
00902     first->nrof = 5;
00903 
00904     second = decrease_ob_nr(first, 3);
00905     fail_unless(second == first, "gem shouldn't be destroyed");
00906 
00907     second = decrease_ob_nr(first, 2);
00908     fail_unless(second == NULL, "decrease_ob_nr should return NULL");
00909     fail_unless(QUERY_FLAG(first, FLAG_FREED), "gem should have been freed");
00910 }
00911 END_TEST
00912 
00916 START_TEST(test_add_weight) {
00917     /*TESTME*/
00918 }
00919 END_TEST
00920 
00924 START_TEST(test_insert_ob_in_ob) {
00925     object *container = NULL;
00926     object *item = NULL;
00927 
00928     item = cctk_create_game_object("gem");
00929     fail_unless(item != NULL, "create gem failed");
00930     item->weight = 50;
00931 
00932     /* Bookshelves have no weight reduction. */
00933     container = cctk_create_game_object("bookshelf");
00934     fail_unless(container != NULL, "create bookshelf failed");
00935 
00936     insert_ob_in_ob(item, container);
00937     fail_unless(container->inv == item, "item not inserted");
00938     fail_unless(container->carrying == 50, "container should carry 50 and not %d", container->carrying);
00939 
00940     remove_ob(item);
00941     fail_unless(container->carrying == 0, "container should carry 0 and not %d", container->carrying);
00942 
00943     /* Sacks have a Str of 10, so will reduce the weight. */
00944     container = cctk_create_game_object("sack");
00945     fail_unless(container != NULL, "create sack failed");
00946 
00947     insert_ob_in_ob(item, container);
00948     fail_unless(container->inv == item, "item not inserted");
00949     fail_unless(container->carrying == 45, "container should carry 45 and not %d", container->carrying);
00950 }
00951 END_TEST
00952 
00956 START_TEST(test_check_move_on) {
00957     /*TESTME*/
00958 }
00959 END_TEST
00960 
00964 START_TEST(test_present_arch) {
00965     /*TESTME*/
00966 }
00967 END_TEST
00968 
00972 START_TEST(test_present) {
00973     /*TESTME*/
00974 }
00975 END_TEST
00976 
00980 START_TEST(test_present_in_ob) {
00981     /*TESTME*/
00982 }
00983 END_TEST
00984 
00988 START_TEST(test_present_in_ob_by_name) {
00989     /*TESTME*/
00990 }
00991 END_TEST
00992 
00996 START_TEST(test_present_arch_in_ob) {
00997     /*TESTME*/
00998 }
00999 END_TEST
01000 
01005 START_TEST(test_flag_inv) {
01006     /*TESTME*/
01007 }
01008 END_TEST
01009 
01013 START_TEST(test_unflag_inv) {
01014     /*TESTME*/
01015 }
01016 END_TEST
01017 
01021 START_TEST(test_set_cheat) {
01022     /*TESTME*/
01023 }
01024 END_TEST
01025 
01029 START_TEST(test_find_free_spot) {
01030     /*TESTME*/
01031 }
01032 END_TEST
01033 
01037 START_TEST(test_find_first_free_spot) {
01038     /*TESTME*/
01039 }
01040 END_TEST
01041 
01045 START_TEST(test_get_search_arr) {
01046     /*TESTME*/
01047 }
01048 END_TEST
01049 
01053 START_TEST(test_find_dir) {
01054     /*TESTME*/
01055 }
01056 END_TEST
01057 
01061 START_TEST(test_distance) {
01062     /*TESTME*/
01063 }
01064 END_TEST
01065 
01069 START_TEST(test_find_dir_2) {
01070     /*TESTME*/
01071 }
01072 END_TEST
01073 
01077 START_TEST(test_absdir) {
01078     /*TESTME*/
01079 }
01080 END_TEST
01081 
01085 START_TEST(test_dirdiff) {
01086     /*TESTME*/
01087 }
01088 END_TEST
01089 
01093 START_TEST(test_can_see_monsterP) {
01094     /*TESTME*/
01095 }
01096 END_TEST
01097 
01101 START_TEST(test_can_pick) {
01102     /*TESTME*/
01103 }
01104 END_TEST
01105 
01109 START_TEST(test_object_create_clone) {
01110     /*TESTME*/
01111 }
01112 END_TEST
01113 
01117 START_TEST(test_was_destroyed) {
01118     /*TESTME*/
01119 }
01120 END_TEST
01121 
01125 START_TEST(test_find_obj_by_type_subtype) {
01126     /*TESTME*/
01127 }
01128 END_TEST
01129 
01133 START_TEST(test_get_ob_key_link) {
01134     /*TESTME*/
01135 }
01136 END_TEST
01137 
01141 START_TEST(test_get_ob_key_value) {
01142     /*TESTME*/
01143 }
01144 END_TEST
01145 
01149 START_TEST(test_set_ob_key_value) {
01150     /*TESTME*/
01151 }
01152 END_TEST
01153 
01157 START_TEST(test_item_matched_string) {
01158     object *pl;
01159     object *o1, *o2;
01160     int val;
01161 
01162     pl = cctk_create_game_object("kobold");
01163     fail_unless(pl != NULL, "couldn't create kobold");
01164     pl->contr = (player *)calloc(1, sizeof(player));
01165     fail_unless(pl->contr != NULL, "couldn't alloc contr");
01166 
01167     o1 = cctk_create_game_object("cloak");
01168     fail_unless(o1 != NULL, "couldn't find cloak archetype");
01169     o1->title = add_string("of Gorokh");
01170     CLEAR_FLAG(o1, FLAG_IDENTIFIED);
01171 
01172     val = item_matched_string(pl, o1, "all");
01173     fail_unless(val == 1, "all didn't match cloak");
01174     val = item_matched_string(pl, o1, "Gorokh");
01175     fail_unless(val == 0, "unidentified cloak matched title with value %d", val);
01176     val = item_matched_string(pl, o1, "random");
01177     fail_unless(val == 0, "unidentified cloak matched random value with value %d", val);
01178 
01179     SET_FLAG(o1, FLAG_IDENTIFIED);
01180     val = item_matched_string(pl, o1, "Gorokh");
01181     fail_unless(val != 0, "identified cloak didn't match title with value %d", val);
01182 
01183     o2 = cctk_create_game_object("cloak");
01184     SET_FLAG(o2, FLAG_UNPAID);
01185     val = item_matched_string(pl, o2, "unpaid");
01186     fail_unless(val == 2, "unpaid cloak didn't match unpaid");
01187     val = item_matched_string(pl, o2, "cloak");
01188     fail_unless(val != 0, "unpaid cloak didn't match cloak with %d", val);
01189     val = item_matched_string(pl, o2, "wrong");
01190     fail_unless(val == 0, "unpaid cloak matched wrong name %d", val);
01191 }
01192 END_TEST
01193 
01194 Suite *object_suite(void) {
01195     Suite *s = suite_create("object");
01196     TCase *tc_core = tcase_create("Core");
01197 
01198     /*setup and teardown will be called before each test in testcase 'tc_core' */
01199     tcase_add_unchecked_fixture(tc_core, setup, teardown);
01200 
01201     suite_add_tcase(s, tc_core);
01202     tcase_add_test(tc_core, test_can_merge);
01203     tcase_add_test(tc_core, test_sum_weight);
01204     tcase_add_test(tc_core, test_object_get_env_recursive);
01205     tcase_add_test(tc_core, test_get_player_container);
01206     tcase_add_test(tc_core, test_dump_object);
01207     tcase_add_test(tc_core, test_dump_all_objects);
01208     tcase_add_test(tc_core, test_find_object);
01209     tcase_add_test(tc_core, test_find_object_name);
01210     tcase_add_test(tc_core, test_free_all_object_data);
01211     tcase_add_test(tc_core, test_get_owner);
01212     tcase_add_test(tc_core, test_clear_owner);
01213     tcase_add_test(tc_core, test_set_owner);
01214     tcase_add_test(tc_core, test_copy_owner);
01215     tcase_add_test(tc_core, test_reset_object);
01216     tcase_add_test(tc_core, test_clear_object);
01217     tcase_add_test(tc_core, test_copy_object);
01218     tcase_add_test(tc_core, test_get_object);
01219     tcase_add_test(tc_core, test_update_turn_face);
01220     tcase_add_test(tc_core, test_update_ob_speed);
01221     tcase_add_test(tc_core, test_remove_from_active_list);
01222     tcase_add_test(tc_core, test_update_object);
01223     tcase_add_test(tc_core, test_free_object);
01224     tcase_add_test(tc_core, test_count_free);
01225     tcase_add_test(tc_core, test_count_used);
01226     tcase_add_test(tc_core, test_count_active);
01227     tcase_add_test(tc_core, test_sub_weight);
01228     tcase_add_test(tc_core, test_remove_ob);
01229     tcase_add_test(tc_core, test_merge_ob);
01230     tcase_add_test(tc_core, test_insert_ob_in_map_at);
01231     tcase_add_test(tc_core, test_insert_ob_in_map);
01232     tcase_add_test(tc_core, test_replace_insert_ob_in_map);
01233     tcase_add_test(tc_core, test_get_split_ob);
01234     tcase_add_test(tc_core, test_decrease_ob_nr);
01235     tcase_add_test(tc_core, test_add_weight);
01236     tcase_add_test(tc_core, test_insert_ob_in_ob);
01237     tcase_add_test(tc_core, test_check_move_on);
01238     tcase_add_test(tc_core, test_present_arch);
01239     tcase_add_test(tc_core, test_present);
01240     tcase_add_test(tc_core, test_present_in_ob);
01241     tcase_add_test(tc_core, test_present_in_ob_by_name);
01242     tcase_add_test(tc_core, test_present_arch_in_ob);
01243     tcase_add_test(tc_core, test_flag_inv);
01244     tcase_add_test(tc_core, test_unflag_inv);
01245     tcase_add_test(tc_core, test_set_cheat);
01246     tcase_add_test(tc_core, test_find_free_spot);
01247     tcase_add_test(tc_core, test_find_first_free_spot);
01248     tcase_add_test(tc_core, test_get_search_arr);
01249     tcase_add_test(tc_core, test_find_dir);
01250     tcase_add_test(tc_core, test_distance);
01251     tcase_add_test(tc_core, test_find_dir_2);
01252     tcase_add_test(tc_core, test_absdir);
01253     tcase_add_test(tc_core, test_dirdiff);
01254     tcase_add_test(tc_core, test_can_see_monsterP);
01255     tcase_add_test(tc_core, test_can_pick);
01256     tcase_add_test(tc_core, test_object_create_clone);
01257     tcase_add_test(tc_core, test_was_destroyed);
01258     tcase_add_test(tc_core, test_find_obj_by_type_subtype);
01259     tcase_add_test(tc_core, test_get_ob_key_link);
01260     tcase_add_test(tc_core, test_get_ob_key_value);
01261     tcase_add_test(tc_core, test_set_ob_key_value);
01262     tcase_add_test(tc_core, test_item_matched_string);
01263 
01264     return s;
01265 }
01266 
01267 int main(void) {
01268     int nf;
01269     SRunner *sr;
01270     Suite *s = object_suite();
01271 
01272     sr = srunner_create(s);
01273     srunner_set_xml(sr, LOGDIR "/unit/common/object.xml");
01274 /* if you wish to debug, uncomment the following line. */
01275 /*  srunner_set_fork_status(sr, CK_NOFORK);*/
01276 
01277     srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
01278     nf = srunner_ntests_failed(sr);
01279     srunner_free(sr);
01280     return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
01281 }