~ubuntu-branches/ubuntu/natty/mimetic/natty

« back to all changes in this revision

Viewing changes to test/cutee.h

  • Committer: Bazaar Package Importer
  • Author(s): gregor herrmann
  • Date: 2006-06-16 13:16:07 UTC
  • Revision ID: james.westby@ubuntu.com-20060616131607-245mqjypkjuahq6b
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    copyright            : (C) 2003-2005 by Stefano Barbato
 
3
    email                : stefano@codesink.org
 
4
 
 
5
    $Id: cutee.h,v 1.11 2005/02/23 10:26:15 tat Exp $
 
6
 ***************************************************************************/
 
7
 
 
8
/***************************************************************************
 
9
 *                                                                         *
 
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.                                   *
 
14
 *                                                                         *
 
15
 ***************************************************************************/
 
16
 
 
17
#ifndef _CUTEE_CUTEE_H_
 
18
#define _CUTEE_CUTEE_H_
 
19
#include <iostream>
 
20
#include <sstream>
 
21
#include <iomanip>
 
22
#include <stdarg.h>
 
23
 
 
24
typedef unsigned int uint;
 
25
 
 
26
#define CUTEE_VERSION "0.4.2"
 
27
 
 
28
#define MAX_TEST_COUNT 1000
 
29
 
 
30
 
 
31
#define TEST_CLASS( name ) \
 
32
    dummy_##name: public cutee::CuteeTest { \
 
33
    public: \
 
34
        dummy_##name() \
 
35
        { \
 
36
            className(#name); \
 
37
            classFileName(__FILE__); \
 
38
            classLineNo(__LINE__); \
 
39
        } \
 
40
    }; \
 
41
    struct name: public dummy_##name
 
42
#define TEST_FUNCTION_EX( funcname, filename, lineno ) \
 
43
    run_##funcname() \
 
44
    { \
 
45
        functionName(#funcname); \
 
46
        functionLineNo(lineno); \
 
47
        mEvt->enterFunction(*this); \
 
48
        mFuncExitCode = 0; \
 
49
        funcname(); \
 
50
        if(mFuncExitCode) mFailed++; \
 
51
        mEvt->leaveFunction(*this, mFuncExitCode == 0); \
 
52
    } \
 
53
    void funcname()
 
54
 
 
55
 
 
56
#define TEST_FUNCTION( funcname ) \
 
57
    TEST_FUNCTION_EX( funcname, __FILE__, __LINE__)
 
58
 
 
59
#define PRINT_VALUE( a ) \
 
60
    "\t[" << #a << ": " << a << "]" << std::endl
 
61
 
 
62
#define PRINT_ON_FAILURE_1( a ) \
 
63
    PRINT_VALUE( 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 )
 
71
 
 
72
#define TEST_ASSERT_EX( e, file, line ) \
 
73
    do { expr(#e); exprFileName(file); exprLineNo(line); \
 
74
    testAssert(e); } while(0)
 
75
 
 
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) 
 
80
 
 
81
 
 
82
 
 
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__ )
 
86
 
 
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__)
 
91
 
 
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__)
 
96
 
 
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__)
 
100
 
 
101
namespace cutee // c++ unit testing environment 
 
102
{
 
103
 
 
104
struct CuteeTest;
 
105
 
 
106
// store runtime context (class name, function name, line numbers, etc.)
 
107
struct Context
 
108
{
 
109
    typedef std::string string;
 
110
    Context()
 
111
    : mClassLineNo(0), mFunctionLineNo(0), mExprLineNo(0) 
 
112
    {}
 
113
    // class info
 
114
    const string& className() const    { return mClassName; }
 
115
    uint classLineNo() const { return mClassLineNo; }
 
116
    const string& classFileName() const { return mClassFileName; }
 
117
    // filename
 
118
    const string& fileName() const { return mFileName; }
 
119
    // function info
 
120
    const string& functionName() const { return mFunctionName; }
 
121
    uint functionLineNo() const { return mFunctionLineNo; }
 
122
    // assertion info
 
123
    const string& expr() const { return mExpr; }
 
124
    const string& exprFileName() const { return mExprFileName; }
 
125
    uint exprLineNo() const { return mExprLineNo; }
 
126
 
 
127
    void className(const string& s) { mClassName = s; }
 
128
    void classFileName(const string& s) { mClassFileName = s; }
 
129
    void classLineNo(uint i) { mClassLineNo = i; }
 
130
 
 
131
    void filename(const string& s) { mFileName = s; }
 
132
 
 
133
    void functionName(const string& s) { mFunctionName = s; }
 
134
    void functionLineNo(uint i) { mFunctionLineNo = i; }
 
135
 
 
136
    void expr(const string& s) { mExpr = s; }
 
137
    void exprFileName(const string& s) { mExprFileName = s; }
 
138
    void exprLineNo(uint i) { mExprLineNo = i; }
 
139
private:
 
140
    std::string mClassName, mClassFileName, mFunctionName, 
 
141
        mFileName, mExpr, mExprFileName;
 
142
    uint mClassLineNo, mFunctionLineNo, mExprLineNo;
 
143
};
 
144
 
 
145
 
 
146
// execution monitor interface
 
147
struct TestRunMonitor
 
148
{
 
149
    virtual ~TestRunMonitor() {}
 
150
    
 
151
    virtual void beginTesting() {}
 
152
    virtual void endTesting() {}
 
153
 
 
154
    // virtual void enterSuite(const CuteeTest&) {}
 
155
    // virtual void leaveSuite(const CuteeTest&, int b) {}
 
156
 
 
157
    virtual void enterClass(const CuteeTest&) {}
 
158
    virtual void leaveClass(const CuteeTest&, int) {}
 
159
 
 
160
    virtual void enterFunction(const CuteeTest&) {}
 
161
    virtual void leaveFunction(const CuteeTest&, int ) {}
 
162
 
 
163
    virtual void assertion(const CuteeTest&, int, 
 
164
        const std::string& u = "") {}
 
165
};
 
166
 
 
167
// statically store pointers to test classes
 
168
struct TestList
 
169
{
 
170
    virtual ~TestList() {}
 
171
    // FIXME add dynamic array alloc to avoid fixed limit
 
172
    static CuteeTest* list[MAX_TEST_COUNT];
 
173
    static int list_idx;
 
174
};
 
175
 
 
176
 
 
177
 
 
178
// this is the base class of all cutee test classes
 
179
struct CuteeTest: public cutee::Context 
 
180
{
 
181
    CuteeTest()
 
182
    : mEvt(&mNullMonitor), mFuncExitCode(0), mFailed(0)
 
183
    {
 
184
    }
 
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;
 
192
protected:
 
193
    void testAssert(int b)
 
194
    {
 
195
        if( b == 0 ) // assertion failed 
 
196
            mFuncExitCode++; 
 
197
        mEvt->assertion(*this, b);
 
198
    }
 
199
    void testAssertM(int b, std::stringstream& os)
 
200
    {
 
201
        if( b == 0 ) // assertion failed 
 
202
            mFuncExitCode++; 
 
203
        mEvt->assertion(*this, b, os.str());
 
204
    }
 
205
protected:
 
206
    TestRunMonitor *mEvt, mNullMonitor;
 
207
    uint mFuncExitCode, mFailed;
 
208
};
 
209
 
 
210
 
 
211
 
 
212
// monitors execution and keep statistics on classes/functions/tests
 
213
struct StatsMonitor: public TestRunMonitor
 
214
{
 
215
    StatsMonitor()
 
216
    : mAssertPassed(0), mAssertFailed(0), mAssertCount(0),
 
217
      mFuncPassed(0),  mFuncFailed(0), mFuncCount(0),
 
218
      mClassPassed(0),  mClassFailed(0), mClassCount(0)
 
219
    {
 
220
    }
 
221
    // void enterSuite(const CuteeTest& t)    {}
 
222
    // void leaveSuite(const CuteeTest& t, int b) {}
 
223
    void enterClass(const CuteeTest& t) 
 
224
    {
 
225
        mClassCount++;
 
226
    }
 
227
    void leaveClass(const CuteeTest& t, int b) 
 
228
    {
 
229
        if(b) 
 
230
            mClassPassed++;
 
231
        else 
 
232
            mClassFailed++;
 
233
    }
 
234
    void enterFunction(const CuteeTest&)
 
235
    {
 
236
        mFuncCount++;
 
237
    }
 
238
    void leaveFunction(const CuteeTest&, int b) 
 
239
    {
 
240
        if(b) 
 
241
            mFuncPassed++;
 
242
        else 
 
243
            mFuncFailed++;
 
244
    }
 
245
    void assertion(const CuteeTest& t, int b, const std::string& userMsg) 
 
246
    {
 
247
        mAssertCount++;
 
248
        if(b) 
 
249
            mAssertPassed++;
 
250
        else 
 
251
            mAssertFailed++;
 
252
    }
 
253
protected:
 
254
    uint mAssertPassed, mAssertFailed, mAssertCount, mFuncPassed,
 
255
         mFuncFailed, mFuncCount, mClassPassed, mClassFailed, mClassCount;
 
256
};
 
257
 
 
258
// keep stats and print results on exit
 
259
struct ConsoleRunMonitor: public StatsMonitor
 
260
{
 
261
    void assertion(const CuteeTest& t, int b, const std::string& userMsg) 
 
262
    {
 
263
        using namespace std;
 
264
        StatsMonitor::assertion(t, b, userMsg);
 
265
        if(!b) 
 
266
        {
 
267
            cout << endl << " [" 
 
268
                << t.exprFileName() << ":" 
 
269
                << t.exprLineNo()<< "] "
 
270
                << t.className() << "::" 
 
271
                << t.functionName() << "(): "
 
272
                << t.expr() << " assertion failed" 
 
273
                << endl;
 
274
            if(!userMsg.empty())
 
275
                cout << userMsg << endl;
 
276
        }
 
277
    }
 
278
    void endTesting()
 
279
    {
 
280
        using namespace std;
 
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;
 
294
    }
 
295
};
 
296
 
 
297
// keep stats and print skimmer xml output on exit
 
298
struct SkimmerRunMonitor: public StatsMonitor
 
299
{
 
300
    void beginTesting() 
 
301
    {
 
302
        using namespace std;
 
303
        cout << "<?xml version=\"1.0\"?>" << endl;
 
304
        cout << "<tests>" << endl;
 
305
    }
 
306
    void endTesting() 
 
307
    {
 
308
        using namespace std;
 
309
        cout << "</tests>" << endl;
 
310
    }
 
311
    void enterClass(const CuteeTest&)
 
312
    {
 
313
    }
 
314
    void leaveClass(const CuteeTest&, int) 
 
315
    {
 
316
    }
 
317
    void enterFunction(const CuteeTest& t) 
 
318
    {
 
319
        using namespace std;
 
320
        cout << "<test>" << endl;
 
321
        cout << "<name>"; 
 
322
        cout << t.className() << "::" << t.functionName() << "()";
 
323
        cout << "</name>" << endl;
 
324
    }
 
325
    void leaveFunction(const CuteeTest& t, int b) 
 
326
    {
 
327
        using namespace std;
 
328
        cout << "<type>" << (b ? "pass" : "fail") << "</type>" << endl;
 
329
        cout << "</test>" << endl << endl << endl;
 
330
    }
 
331
    void assertion(const CuteeTest& t, int b, const std::string& u = "") 
 
332
    {
 
333
        using namespace std;
 
334
        if(b)
 
335
            return;
 
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;
 
342
        if(!u.empty())
 
343
            cout << "  <output>" << u << endl << "  </output>" << endl;
 
344
        cout << "  </expression>" << endl;
 
345
        cout << "  </data>" << endl;
 
346
        cout << "  </info>" << endl << endl;
 
347
    }
 
348
};
 
349
 
 
350
// create the appropriate TestRunMonitor based on environment variables
 
351
// or command line parameters and run tests
 
352
struct Runner
 
353
{
 
354
    Runner(int argc, char** argv)
 
355
    : mEvt(0)
 
356
    {
 
357
        if(getenv("SKIMMER_MODE"))
 
358
            mEvt = new SkimmerRunMonitor;
 
359
        else
 
360
            mEvt = new ConsoleRunMonitor;
 
361
    }
 
362
    void run()
 
363
    {
 
364
        mEvt->beginTesting();
 
365
        for(int i =0; i < TestList::list_idx; i++)
 
366
        {
 
367
            CuteeTest *ct = TestList::list[i];
 
368
            ct->testRunMonitor(mEvt);
 
369
            mEvt->enterClass(*ct);
 
370
            ct->run();
 
371
            mEvt->leaveClass(*ct, ct->passed());
 
372
        }
 
373
        mEvt->endTesting();
 
374
    }
 
375
private:
 
376
    TestRunMonitor *mEvt;
 
377
};
 
378
 
 
379
}
 
380
 
 
381
 
 
382
#endif