00001
00002
00003 #include <wibble/string.h>
00004 #include <iostream>
00005 #include <cstdlib>
00006
00007 #ifndef WIBBLE_TEST_H
00008 #define WIBBLE_TEST_H
00009
00010
00011 extern int assertFailure;
00012
00013 struct Location {
00014 const char *file;
00015 int line;
00016 std::string stmt;
00017 Location( const char *f, int l, std::string st )
00018 : file( f ), line( l ), stmt( st ) {}
00019 };
00020
00021 #define LOCATION(stmt) Location( __FILE__, __LINE__, stmt )
00022 #define assert(x) assert_fn( LOCATION( #x ), x )
00023 #define assert_eq(x, y) assert_eq_fn( LOCATION( #x " == " #y ), x, y )
00024 #define assert_neq(x, y) assert_neq_fn( LOCATION( #x " != " #y ), x, y )
00025 #define assert_list_eq(x, y) \
00026 assert_list_eq_fn( LOCATION( #x " == " #y ), \
00027 sizeof( y ) / sizeof( y[0] ), x, y )
00028
00029 struct AssertFailed {
00030 std::ostream &stream;
00031 std::ostringstream str;
00032 bool expect;
00033 AssertFailed( Location l, std::ostream &s = std::cerr )
00034 : stream( s )
00035 {
00036 expect = assertFailure > 0;
00037 str << l.file << ": " << l.line
00038 << ": assertion `" << l.stmt << "' failed;";
00039 }
00040
00041 ~AssertFailed() {
00042 if ( expect )
00043 ++assertFailure;
00044 else {
00045 stream << str.str() << std::endl;
00046 abort();
00047 }
00048 }
00049 };
00050
00051 template< typename X >
00052 inline AssertFailed &operator<<( AssertFailed &f, X x )
00053 {
00054 f.str << x;
00055 return f;
00056 }
00057
00058 template< typename X >
00059 void assert_fn( Location l, X x )
00060 {
00061 if ( !x ) {
00062 AssertFailed f( l );
00063 }
00064 }
00065
00066 template< typename X, typename Y >
00067 void assert_eq_fn( Location l, X x, Y y )
00068 {
00069 if ( !( x == y ) ) {
00070 AssertFailed f( l );
00071 f << " got ["
00072 << x << "] != [" << y
00073 << "] instead";
00074 }
00075 }
00076
00077 template< typename X >
00078 void assert_list_eq_fn(
00079 Location loc, int c, X l, const typename X::Type check[] )
00080 {
00081 int i = 0;
00082 while ( !l.empty() ) {
00083 if ( l.head() != check[ i ] ) {
00084 AssertFailed f( loc );
00085 f << " list disagrees at position "
00086 << i << ": [" << wibble::str::fmt( l.head() )
00087 << "] != [" << wibble::str::fmt( check[ i ] )
00088 << "]";
00089 }
00090 l = l.tail();
00091 ++ i;
00092 }
00093 if ( i != c ) {
00094 AssertFailed f( loc );
00095 f << " got ["
00096 << i << "] != [" << c << "] instead";
00097 }
00098 }
00099
00100 template< typename X, typename Y >
00101 void assert_neq_fn( Location l, X x, Y y )
00102 {
00103 if ( x != y )
00104 return;
00105 AssertFailed f( l );
00106 f << " got ["
00107 << x << "] == [" << y << "] instead";
00108 }
00109
00110 inline void beginAssertFailure() {
00111 assertFailure = 1;
00112 }
00113
00114 inline void endAssertFailure() {
00115 int f = assertFailure;
00116 assertFailure = 0;
00117 assert( f > 1 );
00118 }
00119
00120 struct ExpectFailure {
00121 ExpectFailure() { beginAssertFailure(); }
00122 ~ExpectFailure() { endAssertFailure(); }
00123 };
00124
00125 typedef void Test;
00126
00127 #endif