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