1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
// -*- C++ -*-
#include <wibble/string.h>
#include <iostream>
#include <cstdlib>
#ifndef WIBBLE_TEST_H
#define WIBBLE_TEST_H
// TODO use TLS
extern int assertFailure;
struct Location {
const char *file;
int line;
std::string stmt;
Location( const char *f, int l, std::string st )
: file( f ), line( l ), stmt( st ) {}
};
#define LOCATION(stmt) Location( __FILE__, __LINE__, stmt )
#define assert(x) assert_fn( LOCATION( #x ), x )
#define assert_eq(x, y) assert_eq_fn( LOCATION( #x " == " #y ), x, y )
#define assert_neq(x, y) assert_neq_fn( LOCATION( #x " != " #y ), x, y )
#define assert_list_eq(x, y) \
assert_list_eq_fn( LOCATION( #x " == " #y ), \
sizeof( y ) / sizeof( y[0] ), x, y )
struct AssertFailed {
std::ostream &stream;
std::ostringstream str;
bool expect;
AssertFailed( Location l, std::ostream &s = std::cerr )
: stream( s )
{
expect = assertFailure > 0;
str << l.file << ": " << l.line
<< ": assertion `" << l.stmt << "' failed;";
}
~AssertFailed() {
if ( expect )
++assertFailure;
else {
stream << str.str() << std::endl;
abort();
}
}
};
template< typename X >
inline AssertFailed &operator<<( AssertFailed &f, X x )
{
f.str << x;
return f;
}
template< typename X >
void assert_fn( Location l, X x )
{
if ( !x ) {
AssertFailed f( l );
}
}
template< typename X, typename Y >
void assert_eq_fn( Location l, X x, Y y )
{
if ( !( x == y ) ) {
AssertFailed f( l );
f << " got ["
<< x << "] != [" << y
<< "] instead";
}
}
template< typename X >
void assert_list_eq_fn(
Location loc, int c, X l, const typename X::Type check[] )
{
int i = 0;
while ( !l.empty() ) {
if ( l.head() != check[ i ] ) {
AssertFailed f( loc );
f << " list disagrees at position "
<< i << ": [" << wibble::str::fmt( l.head() )
<< "] != [" << wibble::str::fmt( check[ i ] )
<< "]";
}
l = l.tail();
++ i;
}
if ( i != c ) {
AssertFailed f( loc );
f << " got ["
<< i << "] != [" << c << "] instead";
}
}
template< typename X, typename Y >
void assert_neq_fn( Location l, X x, Y y )
{
if ( x != y )
return;
AssertFailed f( l );
f << " got ["
<< x << "] == [" << y << "] instead";
}
inline void beginAssertFailure() {
assertFailure = 1;
}
inline void endAssertFailure() {
int f = assertFailure;
assertFailure = 0;
assert( f > 1 );
}
struct ExpectFailure {
ExpectFailure() { beginAssertFailure(); }
~ExpectFailure() { endAssertFailure(); }
};
typedef void Test;
#endif
|