1
/***************************************************************************
2
copyright : (C) 2003-2005 by Stefano Barbato
3
email : stefano@codesink.org
5
$Id: cutee.h,v 1.11 2005/02/23 10:26:15 tat Exp $
6
***************************************************************************/
8
/***************************************************************************
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
***************************************************************************/
17
#ifndef _CUTEE_CUTEE_H_
18
#define _CUTEE_CUTEE_H_
24
typedef unsigned int uint;
26
#define CUTEE_VERSION "0.4.2"
28
#define MAX_TEST_COUNT 1000
31
#define TEST_CLASS( name ) \
32
dummy_##name: public cutee::CuteeTest { \
37
classFileName(__FILE__); \
38
classLineNo(__LINE__); \
41
struct name: public dummy_##name
42
#define TEST_FUNCTION_EX( funcname, filename, lineno ) \
45
functionName(#funcname); \
46
functionLineNo(lineno); \
47
mEvt->enterFunction(*this); \
50
if(mFuncExitCode) mFailed++; \
51
mEvt->leaveFunction(*this, mFuncExitCode == 0); \
56
#define TEST_FUNCTION( funcname ) \
57
TEST_FUNCTION_EX( funcname, __FILE__, __LINE__)
59
#define PRINT_VALUE( a ) \
60
"\t[" << #a << ": " << a << "]" << std::endl
62
#define PRINT_ON_FAILURE_1( a ) \
64
#define PRINT_ON_FAILURE_2( a, b ) \
65
PRINT_VALUE( a ) << PRINT_VALUE( b )
66
#define PRINT_ON_FAILURE_3( a, b, c ) \
67
PRINT_VALUE( a ) << PRINT_VALUE( b ) << PRINT_VALUE( c )
68
#define PRINT_ON_FAILURE_4( a, b, c, d ) \
69
PRINT_VALUE( a ) << PRINT_VALUE( b ) << \
70
PRINT_VALUE( c ) << PRINT_VALUE( d )
72
#define TEST_ASSERT_EX( e, file, line ) \
73
do { expr(#e); exprFileName(file); exprLineNo(line); \
74
testAssert(e); } while(0)
76
#define TEST_ASSERT_EX_M( e, p, file, line ) \
77
do { expr(#e); exprFileName(file); exprLineNo(line); \
78
std::stringstream _l_ss; _l_ss << p << std::endl; \
79
testAssertM(e, _l_ss ); } while(0)
83
#define TEST_ASSERT( expr ) TEST_ASSERT_EX( expr, __FILE__, __LINE__ )
84
#define TEST_ASSERT_EQUALS( a, b ) TEST_ASSERT_EX( (a == b), __FILE__,__LINE__ )
85
#define TEST_ASSERT_DIFFERS( a, b ) TEST_ASSERT_EX( (a != b),__FILE__,__LINE__ )
87
// print p on test fail
88
#define TEST_ASSERT_M( expr , p) TEST_ASSERT_EX_M( expr, p, __FILE__,__LINE__ )
89
#define TEST_ASSERT_EQUALS_M( a, b, p ) TEST_ASSERT_EX_M( (a == b), p,__FILE__,__LINE__ )
90
#define TEST_ASSERT_DIFFERS_M( a, b, p ) TEST_ASSERT_EX_M( (a != b), p,__FILE__,__LINE__)
92
// print a and b on error
93
#define TEST_ASSERT_P( expr ) TEST_ASSERT_EX_M( expr, PRINT_ON_FAILURE_1( expr ), __FILE__,__LINE__ )
94
#define TEST_ASSERT_EQUALS_P( a, b ) TEST_ASSERT_EX_M( (a == b), PRINT_ON_FAILURE_2( a, b ), __FILE__,__LINE__ )
95
#define TEST_ASSERT_DIFFERS_P( a, b ) TEST_ASSERT_EX_M( (a != b), PRINT_ON_FAILURE_2( a, b ), __FILE__,__LINE__)
97
#define TEST_ASSERT_PM( expr, m ) TEST_ASSERT_EX_M( expr, PRINT_ON_FAILURE_2( expr, m ), __FILE__,__LINE__ )
98
#define TEST_ASSERT_EQUALS_PM( a, b, m ) TEST_ASSERT_EX_M( (a == b), PRINT_ON_FAILURE_3( a, b, m ), __FILE__,__LINE__ )
99
#define TEST_ASSERT_DIFFERS_PM( a, b, m ) TEST_ASSERT_EX_M( (a != b), PRINT_ON_FAILURE_3( a, b, m ), __FILE__,__LINE__)
101
namespace cutee // c++ unit testing environment
106
// store runtime context (class name, function name, line numbers, etc.)
109
typedef std::string string;
111
: mClassLineNo(0), mFunctionLineNo(0), mExprLineNo(0)
114
const string& className() const { return mClassName; }
115
uint classLineNo() const { return mClassLineNo; }
116
const string& classFileName() const { return mClassFileName; }
118
const string& fileName() const { return mFileName; }
120
const string& functionName() const { return mFunctionName; }
121
uint functionLineNo() const { return mFunctionLineNo; }
123
const string& expr() const { return mExpr; }
124
const string& exprFileName() const { return mExprFileName; }
125
uint exprLineNo() const { return mExprLineNo; }
127
void className(const string& s) { mClassName = s; }
128
void classFileName(const string& s) { mClassFileName = s; }
129
void classLineNo(uint i) { mClassLineNo = i; }
131
void filename(const string& s) { mFileName = s; }
133
void functionName(const string& s) { mFunctionName = s; }
134
void functionLineNo(uint i) { mFunctionLineNo = i; }
136
void expr(const string& s) { mExpr = s; }
137
void exprFileName(const string& s) { mExprFileName = s; }
138
void exprLineNo(uint i) { mExprLineNo = i; }
140
std::string mClassName, mClassFileName, mFunctionName,
141
mFileName, mExpr, mExprFileName;
142
uint mClassLineNo, mFunctionLineNo, mExprLineNo;
146
// execution monitor interface
147
struct TestRunMonitor
149
virtual ~TestRunMonitor() {}
151
virtual void beginTesting() {}
152
virtual void endTesting() {}
154
// virtual void enterSuite(const CuteeTest&) {}
155
// virtual void leaveSuite(const CuteeTest&, int b) {}
157
virtual void enterClass(const CuteeTest&) {}
158
virtual void leaveClass(const CuteeTest&, int) {}
160
virtual void enterFunction(const CuteeTest&) {}
161
virtual void leaveFunction(const CuteeTest&, int ) {}
163
virtual void assertion(const CuteeTest&, int,
164
const std::string& u = "") {}
167
// statically store pointers to test classes
170
virtual ~TestList() {}
171
// FIXME add dynamic array alloc to avoid fixed limit
172
static CuteeTest* list[MAX_TEST_COUNT];
178
// this is the base class of all cutee test classes
179
struct CuteeTest: public cutee::Context
182
: mEvt(&mNullMonitor), mFuncExitCode(0), mFailed(0)
185
virtual ~CuteeTest() {}
186
virtual void setUp() {}
187
virtual void tearDown() {}
188
void testRunMonitor(TestRunMonitor *evt) { mEvt = evt; }
189
int passed() const { return mFailed == 0; }
190
virtual void run() = 0;
191
virtual uint count() = 0;
193
void testAssert(int b)
195
if( b == 0 ) // assertion failed
197
mEvt->assertion(*this, b);
199
void testAssertM(int b, std::stringstream& os)
201
if( b == 0 ) // assertion failed
203
mEvt->assertion(*this, b, os.str());
206
TestRunMonitor *mEvt, mNullMonitor;
207
uint mFuncExitCode, mFailed;
212
// monitors execution and keep statistics on classes/functions/tests
213
struct StatsMonitor: public TestRunMonitor
216
: mAssertPassed(0), mAssertFailed(0), mAssertCount(0),
217
mFuncPassed(0), mFuncFailed(0), mFuncCount(0),
218
mClassPassed(0), mClassFailed(0), mClassCount(0)
221
// void enterSuite(const CuteeTest& t) {}
222
// void leaveSuite(const CuteeTest& t, int b) {}
223
void enterClass(const CuteeTest& t)
227
void leaveClass(const CuteeTest& t, int b)
234
void enterFunction(const CuteeTest&)
238
void leaveFunction(const CuteeTest&, int b)
245
void assertion(const CuteeTest& t, int b, const std::string& userMsg)
254
uint mAssertPassed, mAssertFailed, mAssertCount, mFuncPassed,
255
mFuncFailed, mFuncCount, mClassPassed, mClassFailed, mClassCount;
258
// keep stats and print results on exit
259
struct ConsoleRunMonitor: public StatsMonitor
261
void assertion(const CuteeTest& t, int b, const std::string& userMsg)
264
StatsMonitor::assertion(t, b, userMsg);
268
<< t.exprFileName() << ":"
269
<< t.exprLineNo()<< "] "
270
<< t.className() << "::"
271
<< t.functionName() << "(): "
272
<< t.expr() << " assertion failed"
275
cout << userMsg << endl;
281
cout << endl << endl;
282
cout << " ======================================" << endl;
283
cout << " Tests Statistics " << endl;
284
cout << " --------------------------------------" << endl;
285
cout << " Functions Checks " << endl;
286
cout << " Success "<< setw(8) << mFuncPassed <<
287
" " << setw(8) << mAssertPassed << endl;
288
cout << " Failed "<< setw(8) << mFuncFailed <<
289
" " << setw(8) << mAssertFailed << endl;
290
cout << " --------------------------------------" << endl;
291
cout << " Total "<< setw(8) << mFuncCount <<
292
" " << setw(8) << mAssertCount << endl;
293
cout << " ======================================" << endl;
297
// keep stats and print skimmer xml output on exit
298
struct SkimmerRunMonitor: public StatsMonitor
303
cout << "<?xml version=\"1.0\"?>" << endl;
304
cout << "<tests>" << endl;
309
cout << "</tests>" << endl;
311
void enterClass(const CuteeTest&)
314
void leaveClass(const CuteeTest&, int)
317
void enterFunction(const CuteeTest& t)
320
cout << "<test>" << endl;
322
cout << t.className() << "::" << t.functionName() << "()";
323
cout << "</name>" << endl;
325
void leaveFunction(const CuteeTest& t, int b)
328
cout << "<type>" << (b ? "pass" : "fail") << "</type>" << endl;
329
cout << "</test>" << endl << endl << endl;
331
void assertion(const CuteeTest& t, int b, const std::string& u = "")
336
cout << " <info>" << endl;
337
cout << " <type>" << (b ? "pass" : "fail") << "</type>" << endl;
338
cout << " <data>" << endl;
339
cout << " <file>" << t.exprFileName() << "</file>" << endl;
340
cout << " <line>" << t.exprLineNo() << "</line>" << endl;
341
cout << " <expression>" << t.expr() << "</expression>" <<endl;
343
cout << " <output>" << u << endl << " </output>" << endl;
344
cout << " </expression>" << endl;
345
cout << " </data>" << endl;
346
cout << " </info>" << endl << endl;
350
// create the appropriate TestRunMonitor based on environment variables
351
// or command line parameters and run tests
354
Runner(int argc, char** argv)
357
if(getenv("SKIMMER_MODE"))
358
mEvt = new SkimmerRunMonitor;
360
mEvt = new ConsoleRunMonitor;
364
mEvt->beginTesting();
365
for(int i =0; i < TestList::list_idx; i++)
367
CuteeTest *ct = TestList::list[i];
368
ct->testRunMonitor(mEvt);
369
mEvt->enterClass(*ct);
371
mEvt->leaveClass(*ct, ct->passed());
376
TestRunMonitor *mEvt;