MOAB: Mesh Oriented datABase  (version 5.2.1)
TestUtil.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines