MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 #ifndef TEST_UTIL_HPP 00002 #define TEST_UTIL_HPP 00003 00004 #ifdef __cplusplus 00005 #include <string> 00006 #endif 00007 #include "moab/MOABConfig.h" 00008 #ifdef MOAB_HAVE_MPI 00009 #include "mpi.h" 00010 #endif 00011 00012 /* Define these here because they are used by many tests 00013 * to find the add directory for input files */ 00014 #define STRINGIFY_( X ) #X 00015 #define STRINGIFY( X ) STRINGIFY_( X ) 00016 00017 #ifdef MESHDIR 00018 #ifdef __cplusplus 00019 const std::string TestDir( STRINGIFY( MESHDIR ) ); 00020 #else 00021 const char* TestDir = STRINGIFY( MESHDIR ); 00022 #endif 00023 #else 00024 #error Specify MESHDIR to compile test 00025 #endif 00026 00027 /* How to use this test suite utility: 00028 * 1) Write tests that use the CHECK and CHECK_* macros defined below to assert test conditions. 00029 * 2) Write a main routine that invokes each test through the RUN_TEST macro 00030 * 3) RUN_TEST evaluates to 1 if test failed, zero otherwize. Count failures and print summary. 00031 */ 00032 00033 /** Check that A is MB_SUCCESS */ 00034 #define CHECK_ERR( A ) check_equal( MB_SUCCESS, ( A ), "MB_SUCCESS", #A, __LINE__, __FILE__ ) 00035 /** Ensure that A is true */ 00036 #define CHECK( A ) check_true( ( A ), #A, __LINE__, __FILE__ ) 00037 /** Check that two values are equal */ 00038 #define CHECK_EQUAL( EXP, ACT ) check_equal( ( EXP ), ( ACT ), #EXP, #ACT, __LINE__, __FILE__ ) 00039 /** Check that two real (float or double) values are equal within EPS */ 00040 #define CHECK_REAL_EQUAL( EXP, ACT, EPS ) check_equal( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ ) 00041 /** Check that two arrays contain the same values in the same order */ 00042 #define CHECK_ARRAYS_EQUAL( EXP, EXP_LEN, ACT, ACT_LEN ) \ 00043 check_array_equal( ( EXP ), ( EXP_LEN ), ( ACT ), ( ACT_LEN ), #EXP, #ACT, __LINE__, __FILE__ ) 00044 /** Check that two CartVect objects contain same values */ 00045 #define CHECK_VECREAL_EQUAL( EXP, ACT, EPS ) \ 00046 check_equal_cartvect( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ ) 00047 /** Run a test 00048 * Argument should be a function with the signature: void func(void) 00049 * Evaluates to zero if test is successful, one otherwise. 00050 */ 00051 #define RUN_TEST( FUNC ) run_test( &FUNC, #FUNC ) 00052 00053 // Use C++ exceptions to return error state to test runner 00054 // Portable, but whole test suite stops if any test segfaults, asserts, etc. 00055 #define EXCEPTION_MODE 1 00056 00057 // Test runner forks separate process for each test. 00058 // Difficult to debug tests (with debugger). Not portable to Windows. 00059 // Very robust (no test can distrub test running code) 00060 #define FORK_MODE 2 00061 00062 // Use signal handler and long jumps to return error state to test runner. 00063 // Might be portable to Windows (not sure). Possibly undefined behavior (e.g. continuing 00064 // with next test after catching segfault is technically undefined behavior.) 00065 // Also, tests can corrupt heap memory management, interferring with later tests. 00066 // Leaks memory on test failure (no stack unwind). This is actually a feature, as 00067 // we don't care too much about tests leaking memory and trying to reconver memory 00068 // might make things worse, depending on why the test failed. 00069 #define LONGJMP_MODE 3 00070 00071 // If test application hasn't set MODE, set to default 00072 #ifndef MODE 00073 #if defined( _MSC_VER ) || defined( __MINGW32__ ) 00074 #define MODE EXCEPTION_MODE 00075 #else 00076 #define MODE LONGJMP_MODE 00077 #endif 00078 #endif 00079 00080 /*************************************************************************************** 00081 * NOTE: The remainder of this file contains the implementation of the above macros. 00082 * The above macros constitute the entire intended API. 00083 ***************************************************************************************/ 00084 00085 #include <math.h> 00086 #include <stdio.h> 00087 #include <stdlib.h> 00088 #include <string.h> 00089 #ifdef __cplusplus 00090 #include <iostream> 00091 #include <vector> 00092 #include <algorithm> 00093 #endif 00094 00095 /*************************************************************************************** 00096 * Define What to do when a test fails. 00097 ***************************************************************************************/ 00098 00099 // For EXCEPTION_MODE, throw an exception when a test fails. 00100 // This will unwind stack, recover memory, etc. 00101 #if MODE == EXCEPTION_MODE 00102 struct ErrorExcept 00103 { 00104 }; 00105 #define FLAG_ERROR throw ErrorExcept() 00106 // For FORK_MODE, the test is running in its own processs. Just 00107 // terminate the process with a non-zero exit code when the test 00108 // fails. 00109 #elif MODE == FORK_MODE 00110 #include <sys/types.h> 00111 #include <sys/wait.h> 00112 #include <unistd.h> 00113 #include <errno.h> 00114 #define FLAG_ERROR exit( 1 ) 00115 // For LONGJMP_MODE, we do a long jump to just before the test is 00116 // run, with a return value of -1 to indicate failures (positive 00117 // return codes are used if the test caused a segfault or other 00118 // signal.) 00119 #elif MODE == LONGJMP_MODE 00120 #include <signal.h> 00121 #include <setjmp.h> 00122 #define FLAG_ERROR siglongjmp( jmpenv, -1 ) 00123 #else 00124 #error "MODE not set" 00125 #endif 00126 00127 /*************************************************************************************** 00128 * Setup for LONGJMP_MODE 00129 ***************************************************************************************/ 00130 00131 #if MODE == LONGJMP_MODE 00132 00133 // Variable to hold stack state for longjmp 00134 sigjmp_buf jmpenv; 00135 00136 // Define signal handler used to catch errors such as segfaults. 00137 // Signal handler does longjmp with the signal number as the 00138 // return value. 00139 extern "C" { 00140 void sighandler( int sig ) 00141 { 00142 signal( sig, sighandler ); 00143 siglongjmp( jmpenv, sig ); 00144 // should never return from longjmp 00145 exit( 1 ); 00146 } 00147 typedef void ( *sigfunc_t )( int ); 00148 } // extern "C" 00149 00150 // Helper function to register signal handlers. 00151 int sethandler( int sig ) 00152 { 00153 sigfunc_t h = signal( sig, &sighandler ); 00154 if( h == SIG_ERR ) return 1; 00155 // If user-defined signal handler (or signal is ignored), 00156 // than unregister our handler. 00157 else if( h != SIG_DFL ) 00158 signal( sig, h ); 00159 return 0; 00160 } 00161 00162 // Register signal handlers for all defined signals that typicall result 00163 // in process termination. 00164 int init_signal_handlers() 00165 { 00166 int result = 0; 00167 /* Don't trap these. It is unlikely that a test would ever generate such 00168 a signal on its own and trapping them interfers with a user's ability 00169 to stop a test. SIGHUP implies that the controlling terminal was closed. 00170 If the user does ctrl-C or ctrl-\ (SIGINT and SIGQUIT, respectively) and 00171 we trap these then just the current test stops. If we leave the default 00172 behavior for them then the whole test suite stops. The latter is likely 00173 the desired behavior. SIGTERM is the default signal sent by the 'kill' 00174 command. 00175 #ifdef SIGHUP 00176 result += sethandler( SIGHUP ); 00177 #endif 00178 #ifdef SIGINT 00179 result += sethandler( SIGINT ); 00180 #endif 00181 #ifdef SIGQUIT 00182 result += sethandler( SIGQUIT ); 00183 #endif 00184 #ifdef SIGTERM 00185 result += sethandler( SIGTERM ); 00186 #endif 00187 */ 00188 00189 #ifdef SIGILL 00190 result += sethandler( SIGILL ); 00191 #endif 00192 #ifdef SIGTRAP 00193 result += sethandler( SIGTRAP ); 00194 #endif 00195 #ifdef SIGABRT 00196 result += sethandler( SIGABRT ); 00197 #endif 00198 #ifdef SIGBUS 00199 result += sethandler( SIGBUS ); 00200 #endif 00201 #ifdef SIGFPE 00202 result += sethandler( SIGFPE ); 00203 #endif 00204 #ifdef SIGSEGV 00205 result += sethandler( SIGSEGV ); 00206 #endif 00207 00208 /* Catching these causes problems with mpich2 1.3.1p1 and a 00209 test should never receive such a signal anyway. 00210 #ifdef SIGUSR1 00211 result += sethandler( SIGUSR1 ); 00212 #endif 00213 #ifdef SIGUSR2 00214 result += sethandler( SIGUSR2 ); 00215 #endif 00216 */ 00217 00218 /* Don't trap SIGCHLD. The only way a test should receive 00219 such a signal is if it actually forked a child process. 00220 That is unlikely, but if it does happen the test probably 00221 wants to handle the signal itself. 00222 #ifdef SIGCHLD 00223 result += sethandler( SIGCHLD ); 00224 #endif 00225 */ 00226 00227 #ifdef SIGPIPE 00228 result += sethandler( SIGPIPE ); 00229 #endif 00230 #ifdef SIGIO 00231 result += sethandler( SIGIO ); 00232 #endif 00233 #ifdef SIGSYS 00234 result += sethandler( SIGSYS ); 00235 #endif 00236 return result; 00237 } 00238 00239 // Declare a garbage global variable. Use variable initialization to 00240 // force call to init_signal_handlers(). 00241 int junk_init_var = init_signal_handlers(); 00242 00243 #endif // LONGJMP_MODE 00244 00245 /*************************************************************************************** 00246 * Function to handle failed tests 00247 ***************************************************************************************/ 00248 00249 // use a function rather than substituting FLAG_ERROR directly 00250 // so we have a convenient place to set a break point 00251 inline void flag_error() 00252 { 00253 FLAG_ERROR; 00254 } 00255 00256 /*************************************************************************************** 00257 * The Code to Run Tests 00258 ***************************************************************************************/ 00259 00260 /* Make sure IS_BUILDING_MB is defined so we can include MBInternals.hpp */ 00261 #include "moab/Types.hpp" 00262 #ifndef IS_BUILDING_MB 00263 #define IS_BUILDING_MB 00264 #include "Internals.hpp" 00265 #undef IS_BUILDING_MB 00266 #else 00267 #include "Internals.hpp" 00268 #endif 00269 00270 #ifndef TEST_USES_ERR_CODES 00271 typedef void ( *test_func )( void ); 00272 int run_test( test_func test, const char* func_name ) 00273 #else 00274 typedef moab::ErrorCode ( *test_func_err )( void ); 00275 int run_test( test_func_err test, const char* func_name ) 00276 #endif 00277 { 00278 // check if we are running parallel MPI tests 00279 int rank = 0; 00280 #ifdef MOAB_HAVE_MPI 00281 int isInit; 00282 MPI_Initialized( &isInit ); 00283 if( isInit ) { MPI_Comm_rank( MPI_COMM_WORLD, &rank ); } 00284 #endif 00285 00286 if( rank == 0 ) printf( "Running %s ...\n", func_name ); 00287 00288 #if MODE == EXCEPTION_MODE 00289 /* On Windows, run all tests in same process. 00290 Flag errors by throwing an exception. 00291 */ 00292 try 00293 { 00294 ( *test )(); 00295 return 0; 00296 } 00297 catch( ErrorExcept ) 00298 { 00299 printf( "[%d] %s: FAILED\n", rank, func_name ); 00300 return 1; 00301 } 00302 catch( ... ) 00303 { 00304 printf( "[%d] %s: UNCAUGHT EXCEPTION\n", rank, func_name ); 00305 return 1; 00306 } 00307 00308 #elif MODE == FORK_MODE 00309 /* For non-Windows OSs, fork() and run test in child process. */ 00310 pid_t pid = fork(); 00311 int status; 00312 00313 /* Fork failed? */ 00314 if( pid == -1 ) 00315 { 00316 perror( "fork()" ); 00317 abort(); /* abort all tests (can't fork child processes) */ 00318 } 00319 00320 /* If child process*/ 00321 if( pid == 0 ) 00322 { 00323 ( *test )(); /* call test function */ 00324 exit( 0 ); /* if function returned, then it succeeded */ 00325 } 00326 00327 /* If here, then parent process */ 00328 00329 /* Wait until child process exits */ 00330 waitpid( pid, &status, 0 ); 00331 00332 /* Check child exit status */ 00333 if( WIFSIGNALED( status ) ) 00334 { 00335 if( WTERMSIG( status ) ) printf( " %s: TERMINATED (signal %d)\n", func_name, (int)WTERMSIG( status ) ); 00336 if( WCOREDUMP( status ) ) printf( " %s: CORE DUMP\n", func_name ); 00337 return 1; 00338 } 00339 else if( WEXITSTATUS( status ) ) 00340 { 00341 printf( " %s: FAILED\n", func_name ); 00342 return 1; 00343 } 00344 else 00345 { 00346 return 0; 00347 } 00348 00349 #elif MODE == LONGJMP_MODE 00350 // Save stack state at this location. 00351 int rval = sigsetjmp( jmpenv, 1 ); 00352 // If rval is zero, then we haven't run the test yet. 00353 // If rval is non-zero then 00354 // a) we ran the test 00355 // b) the test failed 00356 // c) we did a longjmp back to the location where we called setsigjmp. 00357 00358 // run test 00359 if( !rval ) 00360 { 00361 ( *test )(); 00362 return 0; 00363 } 00364 // some check failed 00365 else if( rval == -1 ) 00366 { 00367 printf( " %s: FAILED\n", func_name ); 00368 return 1; 00369 } 00370 // a signal was raised (e.g. segfault) 00371 else 00372 { 00373 printf( " %s: TERMINATED (signal %d)\n", func_name, rval ); 00374 return 1; 00375 } 00376 #else 00377 #error "MODE not set" 00378 #endif // MODE 00379 } 00380 00381 /*************************************************************************************** 00382 * CHECK_EQUAL implementations 00383 ***************************************************************************************/ 00384 00385 // Common implementatation for most types 00386 #define EQUAL_TEST_IMPL( TEST, TYPE ) \ 00387 if( !( TEST ) ) \ 00388 { \ 00389 printf( "Equality Test Failed: %s == %s\n", sA, sB ); \ 00390 printf( " at line %d of '%s'\n", line, file ); \ 00391 printf( " Expected value: %" #TYPE "\n", A ); \ 00392 printf( " Actual value: %" #TYPE "\n", B ); \ 00393 printf( "\n" ); \ 00394 flag_error(); \ 00395 } 00396 00397 void check_equal( int A, int B, const char* sA, const char* sB, int line, const char* file ) 00398 { 00399 EQUAL_TEST_IMPL( A == B, d ) 00400 } 00401 00402 void check_equal( unsigned A, unsigned B, const char* sA, const char* sB, int line, const char* file ) 00403 { 00404 EQUAL_TEST_IMPL( A == B, u ) 00405 } 00406 00407 void check_equal( long A, long B, const char* sA, const char* sB, int line, const char* file ) 00408 { 00409 EQUAL_TEST_IMPL( A == B, ld ) 00410 } 00411 00412 void check_equal( unsigned long A, unsigned long B, const char* sA, const char* sB, int line, const char* file ) 00413 { 00414 EQUAL_TEST_IMPL( A == B, lu ) 00415 } 00416 00417 void check_equal( unsigned long long A, unsigned long long B, const char* sA, const char* sB, int line, 00418 const char* file ) 00419 { 00420 EQUAL_TEST_IMPL( A == B, llu ) 00421 } 00422 00423 void check_equal( long long A, long long B, const char* sA, const char* sB, int line, const char* file ) 00424 { 00425 EQUAL_TEST_IMPL( A == B, lld ) 00426 } 00427 00428 void check_equal( void* A, void* B, const char* sA, const char* sB, int line, const char* file ) 00429 { 00430 EQUAL_TEST_IMPL( A == B, p ) 00431 } 00432 00433 void check_equal( const char* A, const char* B, const char* sA, const char* sB, int line, const char* file ) 00434 { 00435 EQUAL_TEST_IMPL( !strcmp( ( A ), ( B ) ), s ) 00436 } 00437 00438 void check_equal( const std::string& A, const std::string& B, const char* sA, const char* sB, int line, 00439 const char* file ) 00440 { 00441 check_equal( A.c_str(), B.c_str(), sA, sB, line, file ); 00442 } 00443 00444 void check_equal( float A, float B, float eps, const char* sA, const char* sB, int line, const char* file ) 00445 { 00446 EQUAL_TEST_IMPL( fabsf( A - B ) <= eps, f ) 00447 } 00448 00449 void check_equal( double A, double B, double eps, const char* sA, const char* sB, int line, const char* file ) 00450 { 00451 EQUAL_TEST_IMPL( fabs( A - B ) <= eps, f ) 00452 } 00453 00454 const char* mb_error_str( moab::ErrorCode err ) 00455 { 00456 switch( err ) 00457 { 00458 case moab::MB_SUCCESS: 00459 return "Success"; 00460 case moab::MB_INDEX_OUT_OF_RANGE: 00461 return "Index Out of Range"; 00462 case moab::MB_TYPE_OUT_OF_RANGE: 00463 return "Type Out of Range"; 00464 case moab::MB_MEMORY_ALLOCATION_FAILED: 00465 return "Memory Alloc. Failed"; 00466 case moab::MB_ENTITY_NOT_FOUND: 00467 return "Entity Not Found"; 00468 case moab::MB_MULTIPLE_ENTITIES_FOUND: 00469 return "Multiple Entities Found"; 00470 case moab::MB_TAG_NOT_FOUND: 00471 return "Tag Not Found"; 00472 case moab::MB_FILE_DOES_NOT_EXIST: 00473 return "File Not Found"; 00474 case moab::MB_FILE_WRITE_ERROR: 00475 return "File Write Error"; 00476 case moab::MB_NOT_IMPLEMENTED: 00477 return "Not Implemented"; 00478 case moab::MB_ALREADY_ALLOCATED: 00479 return "Already Allocated"; 00480 case moab::MB_VARIABLE_DATA_LENGTH: 00481 return "Variable Data Length"; 00482 case moab::MB_INVALID_SIZE: 00483 return "Invalid Size"; 00484 case moab::MB_UNSUPPORTED_OPERATION: 00485 return "Unsupported Operation"; 00486 case moab::MB_UNHANDLED_OPTION: 00487 return "Unhandled Option"; 00488 case moab::MB_STRUCTURED_MESH: 00489 return "Structured Mesh"; 00490 case moab::MB_FAILURE: 00491 return "Failure"; 00492 default: 00493 return "(unknown)"; 00494 } 00495 } 00496 00497 // Special case for MBErrorCode, use mb_error_str() to print the 00498 // string name of the error code. 00499 void check_equal( moab::ErrorCode A, moab::ErrorCode B, const char* sA, const char* sB, int line, const char* file ) 00500 { 00501 if( A == B ) return; 00502 00503 printf( "ErrorCode Test Failed: %s == %s\n", sA, sB ); 00504 printf( " at line %d of '%s'\n", line, file ); 00505 printf( " Expected value: %s (%d)\n", mb_error_str( A ), (int)A ); 00506 printf( " Actual value: %s (%d)\n", mb_error_str( B ), (int)B ); 00507 printf( "\n" ); 00508 flag_error(); 00509 } 00510 00511 const char* mb_type_str( moab::EntityType type ) 00512 { 00513 switch( type ) 00514 { 00515 case moab::MBVERTEX: 00516 return "Vertex"; 00517 case moab::MBEDGE: 00518 return "Edge"; 00519 case moab::MBTRI: 00520 return "Triangle"; 00521 case moab::MBQUAD: 00522 return "Quadrilateral"; 00523 case moab::MBPOLYGON: 00524 return "Polygon"; 00525 case moab::MBTET: 00526 return "Tetrahedron"; 00527 case moab::MBPYRAMID: 00528 return "Pyramid"; 00529 case moab::MBPRISM: 00530 return "Prism (wedge)"; 00531 case moab::MBKNIFE: 00532 return "Knife"; 00533 case moab::MBHEX: 00534 return "Hexahedron"; 00535 case moab::MBPOLYHEDRON: 00536 return "Polyhedron"; 00537 case moab::MBENTITYSET: 00538 return "Entity (Mesh) Set"; 00539 case moab::MBMAXTYPE: 00540 return "(max type)"; 00541 default: 00542 return "(unknown)"; 00543 } 00544 } 00545 00546 const char* mb_type_str( moab::EntityHandle a ) 00547 { 00548 return mb_type_str( moab::TYPE_FROM_HANDLE( a ) ); 00549 } 00550 /* 00551 void check_equal( moab::EntityHandle A, moab::EntityHandle B, const char* sA, const char* sB, int line, const char* file 00552 ) 00553 { 00554 if (A == B) 00555 return; 00556 00557 printf( "Entity handles not equal: %s == %s\n", sA, sB ); 00558 printf( " at line %d of '%s'\n", line, file ); 00559 if (A) 00560 printf( " Expected value: %lx (%s %ld)\n", (unsigned long)A, mb_type_str( A ), (long)ID_FROM_HANDLE(A) ); 00561 else 00562 printf( " Expected value: 0\n" ); 00563 if (B) 00564 printf( " Actual value: %lx (%s %ld)\n", (unsigned long)B, mb_type_str( B ), (long)ID_FROM_HANDLE(B) ); 00565 else 00566 printf( " Actual value: 0\n" ); 00567 printf( "\n" ); 00568 flag_error(); 00569 } 00570 */ 00571 00572 void check_true( bool cond, const char* str, int line, const char* file ) 00573 { 00574 if( !cond ) 00575 { 00576 printf( "Test Failed: %s\n", str ); 00577 printf( " at line %d of '%s'\n", line, file ); 00578 printf( "\n" ); 00579 flag_error(); 00580 } 00581 } 00582 00583 #ifdef MB_CART_VECT_HPP 00584 00585 void check_equal_cartvect( const moab::CartVect& A, const moab::CartVect& B, double eps, const char* sA, const char* sB, 00586 int line, const char* file ) 00587 { 00588 check_equal( A.length(), B.length(), eps, sA, sB, line, file ); 00589 00590 if( fabs( A[0] - B[0] ) <= eps && fabs( A[1] - B[1] ) <= eps && fabs( A[2] - B[2] ) <= eps ) return; 00591 00592 std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl; 00593 std::cout << " at line " << line << " of '" << file << "'" << std::endl; 00594 00595 std::cout << " Expected: "; 00596 std::cout << A << std::endl; 00597 00598 std::cout << " Actual: "; 00599 std::cout << B << std::endl; 00600 00601 flag_error(); 00602 } 00603 00604 #endif // #ifdef MB_CART_VECT_HPP 00605 00606 #ifdef __cplusplus 00607 00608 template < typename T > 00609 void check_array_equal( const T* A, size_t A_size, const T* B, size_t B_size, const char* sA, const char* sB, int line, 00610 const char* file ) 00611 { 00612 size_t i = 0; 00613 for( ;; ) 00614 { 00615 if( i == A_size && i == B_size ) 00616 return; // equal 00617 else if( i == A_size || i == B_size ) 00618 break; // differene lengths 00619 else if( A[i] != B[i] ) 00620 break; 00621 ++i; 00622 } 00623 00624 std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl; 00625 std::cout << " at line " << line << " of '" << file << "'" << std::endl; 00626 std::cout << " Vectors differ at position " << i << std::endl; 00627 00628 // print at most 10 values, roughly centered on the unequal one 00629 size_t count = 10, num_front_values = std::min( count / 2, i ); 00630 size_t max_len = std::max( A_size, B_size ); 00631 if( i + count - num_front_values > max_len ) 00632 { 00633 if( count > max_len ) 00634 { 00635 num_front_values = i; 00636 count = max_len; 00637 } 00638 else 00639 { 00640 num_front_values = count - ( max_len - i ); 00641 } 00642 } 00643 00644 std::cout << " Expected: "; 00645 if( !A_size ) { std::cout << "(empty)" << std::endl; } 00646 else 00647 { 00648 size_t j = i - num_front_values; 00649 size_t end = std::min( j + count, A_size ); 00650 if( j ) std::cout << "... "; 00651 for( ; j < end; ++j ) 00652 { 00653 if( j == i ) 00654 std::cout << '>' << A[j] << "< "; 00655 else 00656 std::cout << A[j] << " "; 00657 } 00658 if( end != A_size ) std::cout << "..."; 00659 std::cout << std::endl; 00660 } 00661 00662 std::cout << " Actual: "; 00663 if( !B_size ) { std::cout << "(empty)" << std::endl; } 00664 else 00665 { 00666 size_t j = i - num_front_values; 00667 size_t end = std::min( j + count, B_size ); 00668 if( j ) std::cout << "... "; 00669 for( ; j < end; ++j ) 00670 { 00671 if( j == i ) 00672 std::cout << '>' << B[j] << "< "; 00673 else 00674 std::cout << B[j] << " "; 00675 } 00676 if( end != B_size ) std::cout << ", ..."; 00677 std::cout << std::endl; 00678 } 00679 00680 flag_error(); 00681 } 00682 00683 template < typename T > 00684 void check_equal( const std::vector< T >& A, const std::vector< T >& B, const char* sA, const char* sB, int line, 00685 const char* file ) 00686 { 00687 if( A.empty() || B.empty() ) 00688 { 00689 if( A.size() != B.size() ) 00690 { 00691 std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl; 00692 std::cout << " at line " << line << " of '" << file << "'" << std::endl; 00693 std::cout << " Both are not empty " << std::endl; 00694 } 00695 return; 00696 } 00697 check_array_equal( &A[0], A.size(), &B[0], B.size(), sA, sB, line, file ); 00698 } 00699 00700 #ifdef MOAB_RANGE_HPP 00701 00702 void check_equal( const moab::Range& A, const moab::Range& B, const char* sA, const char* sB, int line, 00703 const char* file ) 00704 { 00705 if( A == B ) return; 00706 00707 std::cout << "moab::ErrorCode Test Failed: " << sA << " == " << sB << std::endl; 00708 std::cout << " at line " << line << " of '" << file << "'" << std::endl; 00709 std::cout << " Expected: " << A << std::endl; 00710 std::cout << " Actual : " << B << std::endl; 00711 std::cout << std::endl; 00712 flag_error(); 00713 } 00714 00715 #endif // #ifdef MOAB_RANGE_HPP 00716 00717 #endif /* ifdef __cplusplus */ 00718 00719 #endif