tdeunittest
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 <tqobject.h> 00329 #include <tqstringlist.h> 00330 #include <tqasciidict.h> 00331 00332 #include <tdelibs_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__, TQString::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(TQString(__FILE__) + "[" + TQString::number(__LINE__) + "]: passed " + #expression); \ 00383 } \ 00384 else \ 00385 { \ 00386 failure(TQString(__FILE__) + "[" + TQString::number(__LINE__) + TQString("]: 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(TQString(__FILE__) + "[" + TQString::number(__LINE__) + "]: unexpectedly threw an exception and passed: " + #expression); \ 00407 }\ 00408 else \ 00409 { \ 00410 expectedFailure(TQString(__FILE__) + "[" + TQString::number(__LINE__) + TQString("]: failed to throw an exception on: ") + #expression); \ 00411 } \ 00412 setExceptionRaised(false); 00413 00419 #define SKIP_EXCEPTION(exceptionCatch, expression) \ 00420 skip( __FILE__, __LINE__, TQString("Exception catch: ")\ 00421 .arg(TQString(#exceptionCatch)).arg(TQString(" Test expression: ")).arg(TQString(#expression))) 00422 00426 namespace KUnitTest 00427 { 00432 class TDEUNITTEST_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 TQString &debug) 00458 { 00459 m_debug += debug; 00460 } 00461 00464 TQString 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 TQStringList errorList() const { return m_errorList; } 00486 00488 TQStringList xfailList() const { return m_xfailList; } 00489 00491 TQStringList xpassList() const { return m_xpassList; } 00492 00494 TQStringList skipList() const { return m_skipList; } 00495 00497 TQStringList successList() const { return m_successList; } 00498 00499 private: 00500 TQStringList m_errorList; 00501 TQStringList m_xfailList; 00502 TQStringList m_xpassList; 00503 TQStringList m_skipList; 00504 TQStringList m_successList; 00505 TQString m_debug; 00506 int m_tests; 00507 }; 00508 00509 typedef TQAsciiDict<TestResults> TestResultsListType; 00510 00512 typedef TQAsciiDictIterator<TestResults> TestResultsListIteratorType; 00513 00522 class TDEUNITTEST_EXPORT Tester : public TQObject 00523 { 00524 public: 00525 Tester(const char *name = 0L) 00526 : TQObject(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, TQString msg ) 00548 { 00549 TQString skipEntry; 00550 TQTextStream 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 TQString error; 00573 TQTextStream 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 TQString err; 00590 TQTextStream ts( &err, IO_WriteOnly ); 00591 ts << file << "["<< line <<"]: " 00592 <<" unexpectedly passed on \"" 00593 << str <<"\""; 00594 unexpectedSuccess( err ); 00595 } 00596 else 00597 { 00598 TQString succ; 00599 TQTextStream 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 TQString &message) { m_results->m_successList.append(message); } 00618 00626 void failure(const TQString &message) { m_results->m_errorList.append(message); } 00627 00635 void expectedFailure(const TQString &message) { m_results->m_xfailList.append(message); } 00636 00644 void unexpectedSuccess(const TQString &message) { m_results->m_xpassList.append(message); } 00645 00653 void skipTest(const TQString &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 TDEUNITTEST_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 TQString &str); 00704 00705 TestResultsListType m_resultsList; 00706 TestResults *m_total; 00707 }; 00708 } 00709 00710 TDEUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQRect& r ); 00711 00712 TDEUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQPoint& r ); 00713 00714 TDEUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQSize& r ); 00715 00716 #endif