kunittest
tester.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00586
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