tester.h

Go to the documentation of this file.
00001 /*
00002  * tester.h
00003  *
00004  * Copyright (C)  2004  Zack Rusin <zack@kde.org>
00005  * Copyright (C)  2005  Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * 1. Redistributions of source code must retain the above copyright
00012  *   notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *   notice, this list of conditions and the following disclaimer in the
00015  *   documentation and/or other materials provided with the distribution.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #ifndef TESTER_H
00030 #define TESTER_H
00031 
00325 #include <iostream>
00326 using namespace std;
00327 
00328 #include <qobject.h>
00329 #include <qstringlist.h>
00330 #include <qasciidict.h>
00331 
00332 #include <kdelibs_export.h>
00333 
00339 #define CHECK( x, y ) check( __FILE__, __LINE__, #x, x, y, false )
00340 
00342 #define COMPARE CHECK
00343 
00345 #define VERIFY( x ) CHECK( x, true )
00346 
00355 #define XFAIL( x, y ) check( __FILE__, __LINE__, #x, x, y, true )
00356 
00362 #define SKIP( x ) skip( __FILE__, __LINE__, QString::fromLatin1(#x))
00363 
00371 #define CHECK_EXCEPTION(exceptionCatch, expression) \
00372     try \
00373     { \
00374         expression; \
00375     } \
00376     catch(exceptionCatch) \
00377     { \
00378         setExceptionRaised(true); \
00379     } \
00380     if(exceptionRaised()) \
00381     { \
00382         success(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: passed " + #expression); \
00383     } \
00384     else \
00385     { \
00386         failure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw " \
00387                 "an exception on: ") + #expression); \
00388     } \
00389     setExceptionRaised(false);
00390 
00395 #define XFAIL_EXCEPTION(exceptionCatch, expression) \
00396     try \
00397     { \
00398         expression; \
00399     } \
00400     catch(exceptionCatch) \
00401     { \
00402         setExceptionRaised(true); \
00403     } \
00404     if(exceptionRaised()) \
00405     { \
00406         unexpectedSuccess(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: unexpectedly threw an exception and passed: " + #expression); \
00407     }\
00408     else \
00409     { \
00410         expectedFailure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw an exception on: ") + #expression); \
00411     } \
00412     setExceptionRaised(false);
00413 
00419 #define SKIP_EXCEPTION(exceptionCatch, expression) \
00420     skip( __FILE__, __LINE__, QString("Exception catch: ")\
00421             .arg(QString(#exceptionCatch)).arg(QString(" Test expression: ")).arg(QString(#expression)))
00422 
00426 namespace KUnitTest
00427 {
00432     class KUNITTEST_EXPORT TestResults
00433     {
00434         friend class Tester;
00435 
00436     public:
00437         TestResults() : m_tests( 0 ) {}
00438 
00439         virtual ~TestResults() {}
00440 
00443         virtual void clear()
00444         {
00445             m_errorList.clear();
00446             m_xfailList.clear();
00447             m_xpassList.clear();
00448             m_skipList.clear();
00449             m_successList.clear();
00450             m_debug = "";
00451             m_tests = 0;
00452         }
00453 
00457         virtual void addDebugInfo(const QString &debug)
00458         {
00459             m_debug += debug;
00460         }
00461 
00464         QString debugInfo() const { return m_debug; }
00465 
00467         int testsFinished() const { return m_tests; }
00468 
00470         int errors() const { return m_errorList.count(); }
00471 
00473         int xfails() const { return m_xfailList.count(); }
00474 
00476         int xpasses() const { return m_xpassList.count(); }
00477 
00479         int skipped() const { return m_skipList.count(); }
00480 
00482         int passed() const { return m_successList.count(); }
00483 
00485         QStringList errorList() const { return m_errorList; }
00486 
00488         QStringList xfailList() const { return m_xfailList; }
00489 
00491         QStringList xpassList() const { return m_xpassList; }
00492 
00494         QStringList skipList() const { return m_skipList; }
00495 
00497         QStringList successList() const { return m_successList; }
00498 
00499     private:
00500         QStringList m_errorList;
00501         QStringList m_xfailList;
00502         QStringList m_xpassList;
00503         QStringList m_skipList;
00504         QStringList m_successList;
00505         QString     m_debug;
00506         int         m_tests;
00507     };
00508 
00509     typedef QAsciiDict<TestResults> TestResultsListType;
00510 
00512     typedef QAsciiDictIterator<TestResults> TestResultsListIteratorType;
00513 
00522     class KUNITTEST_EXPORT Tester : public QObject
00523     {
00524     public:
00525         Tester(const char *name = 0L)
00526         : QObject(0L, name), m_results(new TestResults()), m_exceptionState(false)
00527         {}
00528 
00529         virtual ~Tester() { delete m_results; }
00530 
00531     public:
00534         virtual void allTests() = 0;
00535 
00536     public:
00539         virtual TestResults *results() { return m_results; }
00540 
00541     protected:
00547         void skip( const char *file, int line, QString msg )
00548         {
00549             QString skipEntry;
00550             QTextStream ts( &skipEntry, IO_WriteOnly );
00551             ts << file << "["<< line <<"]: " << msg;
00552             skipTest( skipEntry );
00553         }
00554 
00563         template<typename T>
00564         void check( const char *file, int line, const char *str,
00565                     const T  &result, const T &expectedResult,
00566                     bool expectedFail )
00567         {
00568             cout << "check: " << file << "["<< line <<"]" << endl;
00569 
00570             if ( result != expectedResult )
00571             {
00572                 QString error;
00573                 QTextStream ts( &error, IO_WriteOnly );
00574                 ts << file << "["<< line <<"]: failed on \"" <<  str
00575                    <<"\" result = '" << result << "' expected = '" << expectedResult << "'";
00576 
00577                 if ( expectedFail )
00578                     expectedFailure( error );
00579                 else
00580                     failure( error );
00581 
00582             }
00583             else
00584             {
00585                 // then the test passed, but we want to record it if
00586                 // we were expecting a failure
00587                 if (expectedFail)
00588                 {
00589                     QString err;
00590                     QTextStream ts( &err, IO_WriteOnly );
00591                     ts << file << "["<< line <<"]: "
00592                        <<" unexpectedly passed on \""
00593                        <<  str <<"\"";
00594                     unexpectedSuccess( err );
00595                 }
00596                 else
00597                 {
00598                     QString succ;
00599                     QTextStream ts( &succ, IO_WriteOnly );
00600                     ts << file << "["<< line <<"]: "
00601                        <<" passed \""
00602                        <<  str <<"\"";
00603                     success( succ );
00604                 }
00605             }
00606 
00607             ++m_results->m_tests;
00608         }
00609 
00617     void success(const QString &message) { m_results->m_successList.append(message); }
00618 
00626     void failure(const QString &message) { m_results->m_errorList.append(message); }
00627 
00635     void expectedFailure(const QString &message) { m_results->m_xfailList.append(message); }
00636 
00644     void unexpectedSuccess(const QString &message) { m_results->m_xpassList.append(message); }
00645 
00653     void skipTest(const QString &message) { m_results->m_skipList.append(message); }
00654 
00662     void setExceptionRaised(bool state) { m_exceptionState = state; }
00663 
00669     bool exceptionRaised() const
00670     {
00671     return m_exceptionState;
00672     }
00673 
00674     protected:
00675         TestResults *m_results;
00676 
00677     private:
00678 
00679     bool m_exceptionState;
00680     };
00681 
00686     class KUNITTEST_EXPORT SlotTester : public Tester
00687     {
00688         Q_OBJECT
00689 
00690     public:
00691         SlotTester(const char *name = 0L);
00692 
00693         void allTests();
00694 
00695         TestResults *results(const char *sl);
00696 
00697         TestResultsListType &resultsList() { return m_resultsList; }
00698 
00699     signals:
00700         void invoke();
00701 
00702     private:
00703         void invokeMember(const QString &str);
00704 
00705         TestResultsListType  m_resultsList;
00706         TestResults         *m_total;
00707     };
00708 }
00709 
00710 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QRect& r );
00711 
00712 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QPoint& r );
00713 
00714 KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QSize& r );
00715 
00716 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys