Crossfire Server, Branch 1.12
R12190
|
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 }