home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / kunittest / tester.h < prev   
Encoding:
C/C++ Source or Header  |  2006-03-17  |  25.7 KB  |  717 lines

  1. /*
  2.  * tester.h
  3.  *
  4.  * Copyright (C)  2004  Zack Rusin <zack@kde.org>
  5.  * Copyright (C)  2005  Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *   notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in the
  15.  *   documentation and/or other materials provided with the distribution.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #ifndef TESTER_H
  30. #define TESTER_H
  31.  
  32. /*! @mainpage KUnitTest - a UnitTest library for KDE
  33.  *
  34.  * @section contents Contents
  35.  * @li @ref background
  36.  * @li @ref usage
  37.  * @li @ref integration
  38.  * @li @ref module
  39.  * @li @ref advanced
  40.  * @li @ref scripts
  41.  *
  42.  * @section background Background
  43.  *
  44.  * KUnitTest is based on the "in reality no one wants to write tests and
  45.  * if it takes a lot of code no one will. So the less code to write the
  46.  * better" design principle.
  47.  *
  48.  * Copyright and credits:
  49.  * @li (C) 2004 Zack Rusin (original author)
  50.  * @li Brad Hards (import into CVS)
  51.  * @li (C) 2005 Jeroen Wijnhout (GUI, library, module)
  52.  *
  53.  * You are responsible for what you do with it though. It
  54.  * is licensed under a BSD license - read the top of each file.
  55.  *
  56.  * All the GUI related stuff is in kdesdk/kunittest, the core libraries are in kdelibs/kunittest.
  57.  * A simple example modules is in kdelisbs/kunittest/samplemodule.{h,cpp}, however more examples
  58.  * can be found in kdesdk/kunittest/example.
  59.  *
  60.  * There are roughly two ways to use the KUnitTest library. Either you create dynamically
  61.  * loadable modules and use the kunittestmodrunner or kunittestguimodrunner programs to run
  62.  * the tests, or you use the kunittest/kunittestgui library to create your own test runner
  63.  * application.
  64.  *
  65.  * The main parts of the KUnitTest library are:
  66.  * @li runner.{h,cpp} - it is the tester runner, holds all tests and runs
  67.  * them.
  68.  * @li runnergui.{h,cpp} - the GUI wrapper around the runner. The GUI neatly organizes the
  69.  *   test results. With the kunittest helper script it can even add the debug output
  70.  *   to the test results. For this you need to have the kdesdk module installed.
  71.  * @li tester.h - which holds the base of a pure test object (Tester).
  72.  * @li module.h - defines macros to create a dynamically loadable module.
  73.  *
  74.  * @section usage Example usage
  75.  *
  76.  * This section describes how to use the library to create your own tests and runner
  77.  * application.
  78.  *
  79.  * Now lets see how you would add a new test to KUnitTest. You do that by
  80.  * writting a Tester derived class which has an "allTests()" method:
  81.  *
  82.  * @code
  83.  * class SampleTest : public Tester
  84.  * {
  85.  * public:
  86.  *    SampleTest();
  87.  *
  88.  *    void allTests();
  89.  * };
  90.  * @endcode
  91.  *
  92.  * Now in the allTests() method we implement our tests, which might look
  93.  * like:
  94.  *
  95.  * @code
  96.  * void SampleTest::allTests()
  97.  * {
  98.  *    CHECK( 3+3, 6 );
  99.  *    CHECK( QString( "hello%1" ).arg( " world not" ), QString( "hello world" ) );
  100.  * }
  101.  * @endcode
  102.  *
  103.  * CHECK() is implemented using a template, so you get type safe
  104.  * comparison. All that is needed is that the argument types have an
  105.  * @c operator==() defined.
  106.  *
  107.  * Now that you did that the only other thing to do is to tell the
  108.  * framework to add this test case, by using the KUNITTEST_REGISTER_TESTER(x) macro. Just
  109.  * put the following line in the implementation file:
  110.  *
  111.  * @code KUNITTEST_REGISTER_TESTER( SampleTest ); @endcode
  112.  *
  113.  * Note the ;, it is necessary.
  114.  *
  115.  * KUnitTest will do the rest. It will tell you which tests failed, how, what was the expected
  116.  * result, what was the result it got, what was the code that failed and so on. For example for
  117.  * the code above it would output:
  118.  *
  119.  * @verbatim
  120. SampleTest - 1 test passed, 1 test failed
  121.     Unexpected failure:
  122.         sampletest.cpp[38]: failed on "QString( "hello%1" ).arg( " world not" )"
  123.             result = 'hello world not', expected = 'hello world'
  124. @endverbatim
  125.  *
  126.  * If you use the RunnerGUI class then you will be presented with a scrollable list of the
  127.  * test results.
  128.  *
  129.  * @section integration Integration
  130.  *
  131.  * The KUnitTest library is easy to use. Let's say that you have the tests written in the
  132.  * sampletest.h and sampletest.cpp files. Then all you need is a main.cpp file and a Makefile.am.
  133.  * You can copy both from the example file provided with the library. A typical main.cpp file
  134.  * looks like this:
  135.  *
  136.  * @code
  137.  * #include <kaboutdata.h>
  138.  * #include <kapplication.h>
  139.  * #include <kcmdlineargs.h>
  140.  * #include <kcmdlineargs.h>
  141.  * #include <klocale.h>
  142.  * #include <kunittest/runnergui.h>
  143.  *
  144.  * static const char description[] = I18N_NOOP("SampleTests");
  145.  * static const char version[] = "0.1";
  146.  * static KCmdLineOptions options[] = { KCmdLineLastOption };
  147.  *
  148.  * int main( int argc, char** argv )
  149.  * {
  150.  *     KAboutData about("SampleTests", I18N_NOOP("SampleTests"), version, description,
  151.  *                     KAboutData::License_BSD, "(C) 2005 You!", 0, 0, "mail@provider");
  152.  *
  153.  *     KCmdLineArgs::init(argc, argv, &about);
  154.  *     KCmdLineArgs::addCmdLineOptions( options );
  155.  *     KApplication app;
  156.  *
  157.  *     KUnitTest::RunnerGUI runner(0);
  158.  *     runner.show();
  159.  *     app.setMainWidget(&runner);
  160.  *
  161.  *     return app.exec();
  162.  * }
  163.  * @endcode
  164.  *
  165.  * The Makefile.am file will look like:
  166.  *
  167.  * @code
  168.  * INCLUDES = -I$(top_srcdir)/src $(all_includes)
  169.  * METASOURCES = AUTO
  170.  * check_PROGRAMS = sampletests
  171.  * sampletests_SOURCES = main.cpp sampletest.cpp
  172.  * sampletests_LDFLAGS = $(KDE_RPATH) $(all_libraries)
  173.  * sampletests_LDADD = -lkunittest
  174.  * noinst_HEADERS = sampletest.h
  175.  *
  176.  * check:
  177.  *    kunittest $(top_builddir)/src/sampletests SampleTests
  178.  * @endcode
  179.  *
  180.  * Most of this Makefile.am will be self-explanatory. After running
  181.  * "make check" the binary "sampletests" will be built. The reason for
  182.  * adding the extra make target "check" is that you probably do not want
  183.  * to rebuild the test suite everytime you run make.
  184.  *
  185.  * You can run the binary on its own, but you get more functionality if you use
  186.  * the kunittest helper script. The Makefile.am is set up in such
  187.  * a way that this helper script is automatically run after you do a
  188.  * "make check". This scripts take two arguments, the first is the path
  189.  * to the binary to run. The second the application name, in this case SampleTests.
  190.  * This name is important since it is used to let the script communicate with the application
  191.  * via DCOP. The helper scripts relies on the Perl DCOP bindings, so these need to be installed.
  192.  *
  193.  * @section module Creating test modules
  194.  *
  195.  * If you think that writing your own test runner if too much work then you can also
  196.  * use the kunittestermodrunner application or the kunitguimodrunner script to run
  197.  * the tests for you. You do have to put your tests in a dynamically loadable module though.
  198.  * Fortunately KUnitTest comes with a few macros to help you do this.
  199.  *
  200.  * First the good news, you don't have to change the header file sampletest.h. However, we
  201.  * will rename it to samplemodule.h, so we remember we are making a module. The
  202.  * implementation file should be rename to samplemodule.cpp. This file requires some
  203.  * modifications. First we need to include the module.h header:
  204.  *
  205.  * @code
  206.  * #include <kunittest/module.h>
  207.  * @endcode
  208.  *
  209.  * This header file is needed because it defines some macro you'll need. In fact this is
  210.  * how you use them:
  211.  *
  212.  * @code
  213.  * KUNITTEST_MODULE( kunittest_samplemodule, "Tests for sample module" );
  214.  * KUNITTEST_MODULE_REGISTER_TESTER( SimpleSampleTester );
  215.  * KUNITTEST_MODULE_REGISTER_TESTER( SomeSampleTester );
  216.  * @endcode
  217.  *
  218.  * The first macro, KUNITTEST_MODULE(), makes sure that the module can be loaded and that
  219.  * the test classes are created. The first argument "kunittest_samplemodule" is the library
  220.  * name, in this case the library we're creating a kunittest_samplemodule.la module. The
  221.  * second argument is name which will appear in the test runner for this test suite.
  222.  *
  223.  * The tester class are now added by the KUNITTEST_MODULE_REGISTER_TESTER() macro, not the
  224.  * KUNITTEST_REGISTER_TESTER(). The only difference between the two is that you have to
  225.  * pass the module class name to this macro.
  226.  *
  227.  * The Makefile.am is also a bit different, but not much:
  228.  *
  229.  * @code
  230.  * INCLUDES = -I$(top_srcdir)/include $(all_includes)
  231.  * METASOURCES = AUTO
  232.  * check_LTLIBRARIES = kunittest_samplemodule.la
  233.  * kunittest_samplemodule_la_SOURCES = samplemodule.cpp
  234.  * kunittest_samplemodule_la_LIBADD = $(LIB_KUNITTEST)
  235.  * kunittest_samplemodule_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN) $(all_libraries)
  236.  * @endcode
  237.  *
  238.  * The $(KDE_CHECK_PLUGIN) macro is there to make sure a dynamically loadable
  239.  * module is created.
  240.  *
  241.  * After you have built the module you open a Konsole and cd into the build folder. Running
  242.  * the tests in the module is now as easy as:
  243.  *
  244.  * @code
  245.  * $ make check && kunittestmodrunner
  246.  * @endcode
  247.  *
  248.  * The kunittestmodrunner application loads all kunittest_*.la modules in the current
  249.  * directory. The exit code of this console application is the number of unexpected failures.
  250.  *
  251.  * If you want the GUI, you should use the kunittestmod script:
  252.  *
  253.  * @code
  254.  * $ make check && kunittestmod
  255.  * @endcode
  256.  *
  257.  * This script starts kunittestguimodrunner application and a helper script to take
  258.  * care of dealing with debug output.
  259.  *
  260.  * @section advanced Advanced usage
  261.  *
  262.  * Normally you just want to use CHECK(). If you are developing some more
  263.  * tests, and they are run (or not) based on some external dependency,
  264.  * you may need to skip some tests. In this case, rather than doing
  265.  * nothing (or worse, writing a test step that aborts the test run), you
  266.  * might want to use SKIP() to record that. Note that this is just a
  267.  * logging / reporting tool, so you just pass in a string:
  268.  *
  269.  * @code
  270.  *     SKIP( "Test skipped because of lack of foo support." );
  271.  * @endcode
  272.  *
  273.  * Similarly, you may have a test step that you know will fail, but you
  274.  * don't want to delete the test step (because it is showing a bug), but
  275.  * equally you can't fix it right now (eg it would break binary
  276.  * compatibility, or would violate a string freeze). In that case, it
  277.  * might help to use XFAIL(), for "expected failure". The test will still
  278.  * be run, and recorded as a failure (assuming it does fail), but will
  279.  * also be recorded separately. Usage might be as follows:
  280.  *
  281.  * @code
  282.  *     XFAIL( 2+1, 4 );
  283.  * @endcode
  284.  *
  285.  * You can mix CHECK(), SKIP() and XFAIL() within a single Tester derived
  286.  * class.
  287.  *
  288.  *
  289.  * @section exceptions Exceptions
  290.  *
  291.  * KUnitTest comes with simple support for testing whether an exception, such as a function call,
  292.  * throws an exception or not. Simply, for the usual macros there corresponding ones for
  293.  * exception testing: CHECK_EXCEPTION(), XFAIL_EXCEPTION(), and SKIP_EXCEPTION(). They all take two
  294.  * arguments: the expression that will catch the exception, and the expression that is supposed
  295.  * to throw the exception.
  296.  *
  297.  * For example:
  298.  *
  299.  * @code
  300.  * CHECK_EXCEPTION(EvilToothFairyException *, myFunction("I forgot to brush my teeth!"));
  301.  * @endcode
  302.  *
  303.  * @note The exception is not de-allocated in anyway.
  304.  *
  305.  * The macros does not allow introspection of the exceptions, such as testing a supplied
  306.  * identifier code on the exception object or similar; this requires manual coding, such
  307.  * as custom macros.
  308.  *
  309.  * @section scripts Scripts
  310.  *
  311.  * The library comes with several helper scripts:
  312.  *
  313.  * @li kunittest [app] [dcopobject] : Runs the application app and redirects all debug output to the dcopobject.
  314.  * @li kunittestmod --folder [folder] --query [query] : Loads and runs all modules in the folder matching the query. Use a GUI.
  315.  * @li kunittest_debughelper [dcopobject] : A PERL script that is able to redirect debug output to a RunnerGUI instance.
  316.  *
  317.  * These scripts are part of the kdesdk/kunittest module.
  318.  */
  319.  
  320. /*!
  321.  * @file tester.h
  322.  * Defines macros for unit testing as well as some test classes.
  323.  */
  324.  
  325. #include <iostream>
  326. using namespace std;
  327.  
  328. #include <qobject.h>
  329. #include <qstringlist.h>
  330. #include <qasciidict.h>
  331.  
  332. #include <kdelibs_export.h>
  333.  
  334. /*! @def CHECK(x,y)
  335.  * Use this macro to perform an equality check. For example
  336.  *
  337.  * @code CHECK( numberOfErrors(), 0 ); @endcode
  338.  */
  339. #define CHECK( x, y ) check( __FILE__, __LINE__, #x, x, y, false )
  340.  
  341. /// for source-compat with qttestlib: use COMPARE(x,y) if you plan to port to qttestlib later.
  342. #define COMPARE CHECK
  343.  
  344. /// for source-compat with qttestlib: use VERIFY(x) if you plan to port to qttestlib later.
  345. #define VERIFY( x ) CHECK( x, true )
  346.  
  347. /*! @def XFAIL(x,y)
  348.  * Use this macro to perform a check you expect to fail. For example
  349.  *
  350.  * @code XFAIL( numberOfErrors(), 1 ); @endcode
  351.  *
  352.  * If the test fails, it will be counted as such, however it will
  353.  * also be registered separately.
  354.  */
  355. #define XFAIL( x, y ) check( __FILE__, __LINE__, #x, x, y, true )
  356.  
  357. /*! @def SKIP(x)
  358.  * Use this macro to indicate that a test is skipped.
  359.  *
  360.  * @code SKIP("Test skipped because of lack of foo support."); @endcode
  361.  */
  362. #define SKIP( x ) skip( __FILE__, __LINE__, QString::fromLatin1(#x))
  363.  
  364. /*!
  365.  * A macro testing that @p expression throws an exception that is catched
  366.  * with @p exceptionCatch. Use it to test that an expression, such as a function call,
  367.  * throws a certain exception.
  368.  * 
  369.  * @note this macro assumes it's used in a function which is a sub-class of the Tester class.
  370.  */
  371. #define CHECK_EXCEPTION(exceptionCatch, expression) \
  372.     try \
  373.     { \
  374.         expression; \
  375.     } \
  376.     catch(exceptionCatch) \
  377.     { \
  378.         setExceptionRaised(true); \
  379.     } \
  380.     if(exceptionRaised()) \
  381.     { \
  382.         success(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: passed " + #expression); \
  383.     } \
  384.     else \
  385.     { \
  386.         failure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw " \
  387.                 "an exception on: ") + #expression); \
  388.     } \
  389.     setExceptionRaised(false);
  390.  
  391. /*!
  392.  * This macro is similar to XFAIL, but is for exceptions instead. Flags @p expression
  393.  * as being expected to fail to throw an exception that @p exceptionCatch is supposed to catch.
  394.  */
  395. #define XFAIL_EXCEPTION(exceptionCatch, expression) \
  396.     try \
  397.     { \
  398.         expression; \
  399.     } \
  400.     catch(exceptionCatch) \
  401.     { \
  402.         setExceptionRaised(true); \
  403.     } \
  404.     if(exceptionRaised()) \
  405.     { \
  406.         unexpectedSuccess(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: unexpectedly threw an exception and passed: " + #expression); \
  407.     }\
  408.     else \
  409.     { \
  410.         expectedFailure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw an exception on: ") + #expression); \
  411.     } \
  412.     setExceptionRaised(false);
  413.  
  414. /*!
  415.  * This macro is similar to SKIP, but is for exceptions instead. Skip testing @p expression
  416.  * and the @p exceptionCatch which is supposed to catch the exception, and register the test
  417.  * as being skipped.
  418.  */
  419. #define SKIP_EXCEPTION(exceptionCatch, expression) \
  420.     skip( __FILE__, __LINE__, QString("Exception catch: ")\
  421.             .arg(QString(#exceptionCatch)).arg(QString(" Test expression: ")).arg(QString(#expression)))
  422.  
  423. /**
  424.  * Namespace for Unit testing classes
  425.  */
  426. namespace KUnitTest
  427. {
  428.     /*! A simple class that encapsulates a test result. A Tester class usually
  429.      * has a single TestResults instance associated with it, however the SlotTester
  430.      * class can have more TestResults instances (one for each test slot in fact).
  431.      */
  432.     class KUNITTEST_EXPORT TestResults
  433.     {
  434.         friend class Tester;
  435.  
  436.     public:
  437.         TestResults() : m_tests( 0 ) {}
  438.  
  439.         virtual ~TestResults() {}
  440.  
  441.         /*! Clears the test results and debug info. Normally you do not need to call this.
  442.          */
  443.         virtual void clear()
  444.         {
  445.             m_errorList.clear();
  446.             m_xfailList.clear();
  447.             m_xpassList.clear();
  448.             m_skipList.clear();
  449.             m_successList.clear();
  450.             m_debug = "";
  451.             m_tests = 0;
  452.         }
  453.  
  454.         /*! Add some debug info that can be view later. Normally you do not need to call this.
  455.          * @param debug The debug info.
  456.          */
  457.         virtual void addDebugInfo(const QString &debug)
  458.         {
  459.             m_debug += debug;
  460.         }
  461.  
  462.         /*! @returns The debug info that was added to this Tester object.
  463.          */
  464.         QString debugInfo() const { return m_debug; }
  465.  
  466.         /*! @returns The number of finished tests. */
  467.         int testsFinished() const { return m_tests; }
  468.  
  469.         /*! @returns The number of failed tests. */
  470.         int errors() const { return m_errorList.count(); }
  471.  
  472.         /*! @returns The number of expected failures. */
  473.         int xfails() const { return m_xfailList.count(); }
  474.  
  475.         /*! @returns The number of unexpected successes. */
  476.         int xpasses() const { return m_xpassList.count(); }
  477.  
  478.         /*! @returns The number of skipped tests. */
  479.         int skipped() const { return m_skipList.count(); }
  480.  
  481.         /*! @returns The number of passed tests. */
  482.         int passed() const { return m_successList.count(); }
  483.  
  484.         /*! @returns Details about the failed tests. */
  485.         QStringList errorList() const { return m_errorList; }
  486.  
  487.         /*! @returns Details about tests that failed expectedly. */
  488.         QStringList xfailList() const { return m_xfailList; }
  489.  
  490.         /*! @returns Details about tests that succeeded unexpectedly. */
  491.         QStringList xpassList() const { return m_xpassList; }
  492.  
  493.         /*! @returns Details about which tests were skipped. */
  494.         QStringList skipList() const { return m_skipList; }
  495.  
  496.         /*! @returns Details about the succeeded tests. */
  497.         QStringList successList() const { return m_successList; }
  498.  
  499.     private:
  500.         QStringList m_errorList;
  501.         QStringList m_xfailList;
  502.         QStringList m_xpassList;
  503.         QStringList m_skipList;
  504.         QStringList m_successList;
  505.         QString     m_debug;
  506.         int         m_tests;
  507.     };
  508.  
  509.     typedef QAsciiDict<TestResults> TestResultsListType;
  510.  
  511.     /*! A type that can be used to iterate through the registry. */
  512.     typedef QAsciiDictIterator<TestResults> TestResultsListIteratorType;
  513.  
  514.     /*! The abstract Tester class forms the base class for all test cases. Users must
  515.      * implement the void Tester::allTests() method. This method contains the actual test.
  516.      *
  517.      * Use the CHECK(x,y), XFAIL(x,y) and SKIP(x) macros in the allTests() method
  518.      * to perform the tests.
  519.      *
  520.      * @see CHECK, XFAIL, SKIP
  521.      */
  522.     class KUNITTEST_EXPORT Tester : public QObject
  523.     {
  524.     public:
  525.         Tester(const char *name = 0L)
  526.         : QObject(0L, name), m_results(new TestResults()), m_exceptionState(false)
  527.         {}
  528.  
  529.         virtual ~Tester() { delete m_results; }
  530.  
  531.     public:
  532.         /*! Implement this method with the tests and checks you want to perform.
  533.          */
  534.         virtual void allTests() = 0;
  535.  
  536.     public:
  537.         /*! @return The TestResults instance.
  538.          */
  539.         virtual TestResults *results() { return m_results; }
  540.  
  541.     protected:
  542.         /*! This is called when the SKIP(x) macro is used.
  543.          * @param file A C-string containing the name of the file where the skipped tests resides. Typically the __FILE__ macro is used to retrieve the filename.
  544.          * @param line The linenumber in the file @p file. Use the __LINE__ macro for this.
  545.          * @param msg The message that identifies the skipped test.
  546.          */
  547.         void skip( const char *file, int line, QString msg )
  548.         {
  549.             QString skipEntry;
  550.             QTextStream ts( &skipEntry, IO_WriteOnly );
  551.             ts << file << "["<< line <<"]: " << msg;
  552.             skipTest( skipEntry );
  553.         }
  554.  
  555.         /*! This is called when the CHECK or XFAIL macro is used.
  556.          * @param file A C-string containing the name of the file where the skipped tests resides. Typically the __FILE__ macro is used to retrieve the filename.
  557.          * @param line The linenumber in the file @p file. Use the __LINE__ macro for this.
  558.          * @param str The message that identifies the skipped test.
  559.          * @param result The result of the test.
  560.          * @param expectedResult The expected result.
  561.          * @param expectedFail Indicates whether or not a failure is expected.
  562.          */
  563.         template<typename T>
  564.         void check( const char *file, int line, const char *str,
  565.                     const T  &result, const T &expectedResult,
  566.                     bool expectedFail )
  567.         {
  568.             cout << "check: " << file << "["<< line <<"]" << endl;
  569.  
  570.             if ( result != expectedResult )
  571.             {
  572.                 QString error;
  573.                 QTextStream ts( &error, IO_WriteOnly );
  574.                 ts << file << "["<< line <<"]: failed on \"" <<  str
  575.                    <<"\" result = '" << result << "' expected = '" << expectedResult << "'";
  576.  
  577.                 if ( expectedFail )
  578.                     expectedFailure( error );
  579.                 else
  580.                     failure( error );
  581.  
  582.             }
  583.             else
  584.             {
  585.                 // then the test passed, but we want to record it if
  586.                 // we were expecting a failure
  587.                 if (expectedFail)
  588.                 {
  589.                     QString err;
  590.                     QTextStream ts( &err, IO_WriteOnly );
  591.                     ts << file << "["<< line <<"]: "
  592.                        <<" unexpectedly passed on \""
  593.                        <<  str <<"\"";
  594.                     unexpectedSuccess( err );
  595.                 }
  596.                 else
  597.                 {
  598.                     QString succ;
  599.                     QTextStream ts( &succ, IO_WriteOnly );
  600.                     ts << file << "["<< line <<"]: "
  601.                        <<" passed \""
  602.                        <<  str <<"\"";
  603.                     success( succ );
  604.                 }
  605.             }
  606.  
  607.             ++m_results->m_tests;
  608.         }
  609.  
  610.     /*!
  611.      * This function can be used to flag succeeding tests, when 
  612.      * doing customized tests while not using the check function.
  613.      *
  614.      * @param message the message describing what failed. Should be informative, 
  615.      * such as mentioning the expression that failed and where, the file and file number.
  616.      */
  617.     void success(const QString &message) { m_results->m_successList.append(message); }
  618.  
  619.     /*!
  620.      * This function can be used to flag failing tests, when 
  621.      * doing customized tests while not using the check function.
  622.      *
  623.      * @param message the message describing what failed. Should be informative, 
  624.      * such as mentioning the expression that failed and where, the file name and file number.
  625.      */
  626.     void failure(const QString &message) { m_results->m_errorList.append(message); }
  627.  
  628.     /*!
  629.      * This function can be used to flag expected failures, when 
  630.      * doing customized tests while not using the check function.
  631.      *
  632.      * @param message the message describing what failed. Should be informative, 
  633.      * such as mentioning the expression that failed and where, the file name and file number.
  634.      */
  635.     void expectedFailure(const QString &message) { m_results->m_xfailList.append(message); }
  636.  
  637.     /*!
  638.      * This function can be used to flag unexpected successes, when 
  639.      * doing customized tests while not using the check function.
  640.      *
  641.      * @param message the message describing what failed. Should be informative, 
  642.      * such as mentioning the expression that failed and where, the file name and file number.
  643.      */
  644.     void unexpectedSuccess(const QString &message) { m_results->m_xpassList.append(message); }
  645.  
  646.     /*!
  647.      * This function can be used to flag a test as skipped, when 
  648.      * doing customized tests while not using the check function.
  649.      *
  650.      * @param message the message describing what failed. Should be informative, 
  651.      * such as mentioning the expression that failed and where, the file name and file number.
  652.      */
  653.     void skipTest(const QString &message) { m_results->m_skipList.append(message); }
  654.  
  655.     /*!
  656.      * exceptionRaised and exceptionState are book-keeping functions for testing for
  657.      * exceptions. setExceptionRaised sets an internal boolean to true.
  658.      *
  659.      * @see exceptionRaised
  660.      * @param state the new 
  661.      */
  662.     void setExceptionRaised(bool state) { m_exceptionState = state; }
  663.  
  664.     /*!
  665.      * Returns what the currently tested exception state.
  666.      *
  667.      * @see setExceptionRaised
  668.      */
  669.     bool exceptionRaised() const
  670.     {
  671.     return m_exceptionState;
  672.     }
  673.  
  674.     protected:
  675.         TestResults *m_results;
  676.  
  677.     private:
  678.  
  679.     bool m_exceptionState;
  680.     };
  681.  
  682.     /*! The SlotTester class is a special Tester class, one that will
  683.      * execute all slots that start with the string "test". The method
  684.      * void allTests() is implemented and should not be overriden.
  685.      */
  686.     class KUNITTEST_EXPORT SlotTester : public Tester
  687.     {
  688.         Q_OBJECT
  689.  
  690.     public:
  691.         SlotTester(const char *name = 0L);
  692.  
  693.         void allTests();
  694.  
  695.         TestResults *results(const char *sl);
  696.  
  697.         TestResultsListType &resultsList() { return m_resultsList; }
  698.  
  699.     signals:
  700.         void invoke();
  701.  
  702.     private:
  703.         void invokeMember(const QString &str);
  704.  
  705.         TestResultsListType  m_resultsList;
  706.         TestResults         *m_total;
  707.     };
  708. }
  709.  
  710. KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QRect& r );
  711.  
  712. KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QPoint& r );
  713.  
  714. KUNITTEST_EXPORT QTextStream& operator<<( QTextStream& str, const QSize& r );
  715.  
  716. #endif
  717.