wibble 1.1
test.h
Go to the documentation of this file.
1// -*- C++ -*-
2
3#include <wibble/string.h>
4#include <iostream>
5#include <cstdlib>
6
7#ifndef WIBBLE_TEST_H
8#define WIBBLE_TEST_H
9
10namespace wibble {
11
12// TODO use TLS
13extern int assertFailure;
14
15struct Location {
16 const char *file;
18 std::string stmt;
19 Location( const char *f, int l, std::string st, int iter = -1 )
20 : file( f ), line( l ), iteration( iter ), stmt( st ) {}
21};
22
23#define LOCATION(stmt) ::wibble::Location( __FILE__, __LINE__, stmt )
24
25#undef assert // silence a gcc warning if we had assert.h included
26
27#ifndef NDEBUG
28#define LOCATION_I(stmt, i) ::wibble::Location( __FILE__, __LINE__, stmt, i )
29
30#define assert(x) assert_fn( LOCATION( #x ), x )
31#define assert_pred(p, x) assert_pred_fn( \
32 LOCATION( #p "( " #x " )" ), x, p( x ) )
33#define assert_eq(x, y) assert_eq_fn( LOCATION( #x " == " #y ), x, y )
34#define assert_leq(x, y) assert_leq_fn( LOCATION( #x " <= " #y ), x, y )
35#define assert_eq_l(i, x, y) assert_eq_fn( LOCATION_I( #x " == " #y, i ), x, y )
36#define assert_neq(x, y) assert_neq_fn( LOCATION( #x " != " #y ), x, y )
37#define assert_list_eq(x, y) \
38 assert_list_eq_fn( LOCATION( #x " == " #y ), \
39 sizeof( y ) / sizeof( y[0] ), x, y )
40#else
41#define assert(x) ((void)0)
42#define assert_pred(p, x) ((void)0)
43#define assert_eq(x, y) ((void)0)
44#define assert_leq(x, y) ((void)0)
45#define assert_eq_l(i, x, y) ((void)0)
46#define assert_neq(x, y) ((void)0)
47#define assert_list_eq(x, y) ((void)0)
48#endif
49
50#define assert_unreachable(...) assert_die_fn( LOCATION( wibble::str::fmtf(__VA_ARGS__) ) )
51#define assert_unimplemented() assert_die_fn( LOCATION( "not imlemented" ) )
52#define assert_die() assert_die_fn( LOCATION( "forbidden code path tripped" ) )
53
55 std::ostream &stream;
56 std::ostringstream str;
57 bool expect;
58 AssertFailed( Location l, std::ostream &s = std::cerr )
59 : stream( s )
60 {
62 str << l.file << ": " << l.line;
63 if ( l.iteration != -1 )
64 str << " (iteration " << l.iteration << ")";
65 str << ": assertion `" << l.stmt << "' failed;";
66 }
67
69 if ( expect )
71 else {
72 stream << str.str() << std::endl;
73 abort();
74 }
75 }
76};
77
78template< typename X >
80{
81 f.str << x;
82 return f;
83}
84
85template< typename X >
86void assert_fn( Location l, X x )
87{
88 if ( !x ) {
89 AssertFailed f( l );
90 }
91}
92
93void assert_die_fn( Location l ) __attribute__((noreturn));
94
95template< typename X, typename Y >
96void assert_eq_fn( Location l, X x, Y y )
97{
98 if ( !( x == y ) ) {
99 AssertFailed f( l );
100 f << " got ["
101 << x << "] != [" << y
102 << "] instead";
103 }
104}
105
106template< typename X, typename Y >
108{
109 if ( !( x <= y ) ) {
110 AssertFailed f( l );
111 f << " got ["
112 << x << "] > [" << y
113 << "] instead";
114 }
115}
116
117template< typename X >
118void assert_pred_fn( Location l, X x, bool p )
119{
120 if ( !p ) {
121 AssertFailed f( l );
122 f << " for " << x;
123 }
124}
125
126template< typename X >
128 Location loc, int c, X l, const typename X::Type check[] )
129{
130 int i = 0;
131 while ( !l.empty() ) {
132 if ( l.head() != check[ i ] ) {
133 AssertFailed f( loc );
134 f << " list disagrees at position "
135 << i << ": [" << wibble::str::fmt( l.head() )
136 << "] != [" << wibble::str::fmt( check[ i ] )
137 << "]";
138 }
139 l = l.tail();
140 ++ i;
141 }
142 if ( i != c ) {
143 AssertFailed f( loc );
144 f << " got ["
145 << i << "] != [" << c << "] instead";
146 }
147}
148
149template< typename X, typename Y >
151{
152 if ( x != y )
153 return;
154 AssertFailed f( l );
155 f << " got ["
156 << x << "] == [" << y << "] instead";
157}
158
159inline void beginAssertFailure() {
160 assertFailure = 1;
161}
162
163inline void endAssertFailure() {
164#ifndef NDEBUG
165 const int f = assertFailure;
166 assertFailure = 0;
167#endif
168 assert( f > 1 );
169}
170
175
176}
177
178typedef void Test;
179
180#endif
std::string fmt(const char *f,...)
Definition string.cpp:123
Definition amorph.h:17
void assert_list_eq_fn(Location loc, int c, X l, const typename X::Type check[])
Definition test.h:127
void assert_die_fn(Location l)
Definition test.cpp:6
void assert_fn(Location l, X x)
Definition test.h:86
void endAssertFailure()
Definition test.h:163
void assert_leq_fn(Location l, X x, Y y)
Definition test.h:107
void assert_neq_fn(Location l, X x, Y y)
Definition test.h:150
int assertFailure
Definition test.cpp:4
void assert_eq_fn(Location l, X x, Y y)
Definition test.h:96
void assert_pred_fn(Location l, X x, bool p)
Definition test.h:118
void beginAssertFailure()
Definition test.h:159
std::ostream & operator<<(std::ostream &o, const std::pair< X, Y > &x)
Definition parse.h:52
Definition test.h:54
bool expect
Definition test.h:57
AssertFailed(Location l, std::ostream &s=std::cerr)
Definition test.h:58
std::ostringstream str
Definition test.h:56
std::ostream & stream
Definition test.h:55
~AssertFailed()
Definition test.h:68
Definition test.h:171
~ExpectFailure()
Definition test.h:173
ExpectFailure()
Definition test.h:172
Definition test.h:15
int line
Definition test.h:17
int iteration
Definition test.h:17
const char * file
Definition test.h:16
Location(const char *f, int l, std::string st, int iter=-1)
Definition test.h:19
std::string stmt
Definition test.h:18
Definition amorph.h:30
void Test
Definition test.h:178
#define assert(x)
Definition test.h:30