diff options
Diffstat (limited to 'kunittest')
-rw-r--r-- | kunittest/CMakeLists.txt | 52 | ||||
-rw-r--r-- | kunittest/Makefile.am | 27 | ||||
-rw-r--r-- | kunittest/modrunner.cpp | 67 | ||||
-rw-r--r-- | kunittest/module.h | 120 | ||||
-rw-r--r-- | kunittest/runner.cpp | 322 | ||||
-rw-r--r-- | kunittest/runner.h | 219 | ||||
-rw-r--r-- | kunittest/samplemodule.cpp | 40 | ||||
-rw-r--r-- | kunittest/samplemodule.h | 38 | ||||
-rw-r--r-- | kunittest/tester.cpp | 99 | ||||
-rw-r--r-- | kunittest/tester.h | 716 |
10 files changed, 0 insertions, 1700 deletions
diff --git a/kunittest/CMakeLists.txt b/kunittest/CMakeLists.txt deleted file mode 100644 index 74ab23e13..000000000 --- a/kunittest/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/tdecore -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### headers ################################### - -install( FILES runner.h tester.h module.h - DESTINATION ${INCLUDE_INSTALL_DIR}/kunittest ) - - -##### libkunittest ############################## - -set( target kunittest ) - -set( ${target}_SRCS - runner.cpp tester.cpp -) - -tde_add_library( ${target} SHARED AUTOMOC - SOURCES ${${target}_SRCS} - VERSION 1.0.0 - LINK tdecore-shared - DESTINATION ${LIB_INSTALL_DIR} -) - - -##### kunittestmodrunner ######################## - -tde_add_executable( kunittestmodrunner - SOURCES modrunner.cpp - LINK kunittest-shared - DESTINATION ${BIN_INSTALL_DIR} -) diff --git a/kunittest/Makefile.am b/kunittest/Makefile.am deleted file mode 100644 index 9ce5040d7..000000000 --- a/kunittest/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -INCLUDES = $(all_includes) -METASOURCES = AUTO - -lib_LTLIBRARIES = libkunittest.la -libkunittest_la_SOURCES = runner.cpp tester.cpp -libkunittest_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -version-info 1:0:0 -libkunittest_la_LIBADD = $(LIB_TDECORE) $(LIB_QT) - -libkunittestinclude_HEADERS = runner.h tester.h module.h -libkunittestincludedir = $(includedir)/kunittest - -bin_PROGRAMS = kunittestmodrunner -kunittestmodrunner_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -lktexteditor -kunittestmodrunner_LDADD = libkunittest.la $(LIB_TDECORE) -kunittestmodrunner_SOURCES = modrunner.cpp - -# The check_ target makes sure we don't install the modules, -# $(KDE_CHECK_PLUGIN) assures a shared library is created. -check_LTLIBRARIES = kunittest_samplemodule.la -kunittest_samplemodule_la_SOURCES = samplemodule.cpp -kunittest_samplemodule_la_LIBADD = libkunittest.la -kunittest_samplemodule_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN) $(all_libraries) - -check-local: - ./kunittestmodrunner - -include ../admin/Doxyfile.am diff --git a/kunittest/modrunner.cpp b/kunittest/modrunner.cpp deleted file mode 100644 index 93dcff8ef..000000000 --- a/kunittest/modrunner.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <kdebug.h> -#include <kglobal.h> -#include <kinstance.h> -#include <kaboutdata.h> -#include <kcmdlineargs.h> -#include <klocale.h> - -#include "runner.h" - -static const char description[] = - I18N_NOOP("A command-line application that can be used to run KUnitTest modules."); - -static const char version[] = "0.1"; - -static KCmdLineOptions options[] = -{ - {"query [regexp]", I18N_NOOP("Only run modules whose filenames match the regexp."), "^kunittest_.*\\.la$"}, - {"folder [folder]", I18N_NOOP("Only run tests modules which are found in the folder. Use the query option to select modules."), "."}, - { "enable-dbgcap", I18N_NOOP("Disables debug capturing. You typically use this option when you use the GUI."), 0}, - KCmdLineLastOption -}; - - -int main( int argc, char **argv ) -{ - TDEInstance instance("modrunner"); - - TDEAboutData about("KUnitTest Module Runner", I18N_NOOP("KUnitTest ModRunner"), version, description, - TDEAboutData::License_BSD, "(C) 2005 Jeroen Wijnhout", 0, 0, - "Jeroen.Wijnhout@kdemail.net"); - - TDECmdLineArgs::init(argc, argv, &about); - TDECmdLineArgs::addCmdLineOptions( options ); - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - - KUnitTest::Runner::loadModules(args->getOption("folder"), args->getOption("query")); - KUnitTest::Runner::setDebugCapturingEnabled(args->isSet("enable-dbgcap")); - - KUnitTest::Runner::self()->runTests(); - - return KUnitTest::Runner::self()->numberOfFailedTests() - KUnitTest::Runner::self()->numberOfExpectedFailures(); -} diff --git a/kunittest/module.h b/kunittest/module.h deleted file mode 100644 index 7f4b24789..000000000 --- a/kunittest/module.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*! - * @file module.h - * Provides macros to ease building unit tests as shared libraries - */ - -#ifndef KUNITTEST_MODULE_H -#define KUNITTEST_MODULE_H - -#include <tqstring.h> - -#include <klibloader.h> -#include <kunittest/runner.h> - -namespace KUnitTest -{ - /*! @def KUNITTEST_MODULE(library,suite) - * Use this macro if you are creating a KUnitTest module named library. - * This macro creates a module-class named a factory class. The module - * will appear under the name suite in the test runner. - * There is no need in calling the K_EXPORT_COMPONENT_FACTORY macro, - * this is taken care of automatically. - * - * @code KUNITTEST_MODULE(kunittest_samplemodule,"TestSuite") @endcode - */ - #define KUNITTEST_MODULE(library,suite) \ - static const TQString s_kunittest_suite = TQString::fromLatin1(suite); \ - class library##Module : public TQObject \ - { \ - public: \ - library##Module() \ - { \ - KUnitTest::RegistryIteratorType it(s_registry); \ - for( ; it.current(); ++it ) \ - KUnitTest::Runner::registerTester(it.currentKey(), it.current()); \ - } \ - \ - static KUnitTest::RegistryType s_registry; \ - }; \ - \ - KUnitTest::RegistryType library##Module::s_registry; \ - \ - void kunittest_registerModuleTester(const char *name, KUnitTest::Tester *test) \ - { \ - library##Module::s_registry.insert(name, test); \ - } \ - \ - class module##Factory : public KLibFactory \ - { \ - public: \ - TQObject *createObject (TQObject *, const char *, const char *, const TQStringList &) \ - { \ - return new library##Module(); \ - }; \ - }; \ - \ - K_EXPORT_COMPONENT_FACTORY( library, module##Factory ) - - /*! @def KUNITTEST_MODULE_REGISTER_TESTER(tester) - * Use this macro to add a tester class to your module. The name of the tester will - * be identical to the class name. - * - * @code KUNITTEST_MODULE_REGISTER_TESTER(SimpleSampleTester) @endcode - */ - #define KUNITTEST_MODULE_REGISTER_TESTER( tester) \ - static class tester##ModuleAutoregister \ - { \ - public: \ - tester##ModuleAutoregister() \ - { \ - KUnitTest::Tester *test = new tester(); \ - TQString name = s_kunittest_suite + TQString::fromLatin1("::") + TQString::fromLocal8Bit(#tester); \ - test->setName(name.local8Bit()); \ - kunittest_registerModuleTester(name.local8Bit(), test ); \ - } \ - } tester##ModuleAutoregisterInstance; - - /*! @def KUNITTEST_MODULE_REGISTER_NAMEDTESTER(name,tester) - * Use this macro to add a tester class, with specified name, to your module.. - * - * @code KUNITTEST_MODULE_REGISTER_TESTER("SubSuite::PrettyName",SimpleSampleTester) @endcode - */ - #define KUNITTEST_MODULE_REGISTER_NAMEDTESTER( name , tester) \ - static class tester##ModuleAutoregister \ - { \ - public: \ - tester##ModuleAutoregister() \ - { \ - TQString fullName = s_kunittest_suite + TQString("::") + TQString::fromLocal8Bit(name); \ - KUnitTest::Tester *test = new tester(fullName.local8Bit()); \ - kunittest_registerModuleTester(fullName.local8Bit(), test); \ - } \ - } tester##ModuleAutoregisterInstance; -} - -#endif diff --git a/kunittest/runner.cpp b/kunittest/runner.cpp deleted file mode 100644 index e3a8830bb..000000000 --- a/kunittest/runner.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * - * Copyright (C) 2004 Zack Rusin <zack@kde.org> - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <iostream> -using namespace std; - -#include <tqregexp.h> -#include <tqdir.h> -#include <tqmetaobject.h> - -#include <kdebug.h> -#include <klibloader.h> -#include <kglobal.h> -#include <kstandarddirs.h> - -#include "runner.h" -#include "tester.h" - -namespace KUnitTest -{ - Runner *Runner::s_self = 0L; - bool Runner::s_debugCapturingEnabled = false; - - void Runner::registerTester(const char *name, Tester *test) - { - Runner::self()->m_registry.insert(name, test); - } - - void Runner::loadModules(const TQString &folder, const TQString &query) - { - TQRegExp reQuery(query); - TQDir dir(folder, "kunittest_*.la"); - - // Add the folder to the "module" resource such that the KLibLoader can - // find the modules in this folder. - TDEGlobal::dirs()->addResourceDir("module", folder); - kdDebug() << "Looking in folder: " << dir.absPath() << endl; - - // Get a list of all modules. - TQStringList modules = dir.entryList(); - - for ( uint i = 0; i < modules.count(); ++i ) - { - TQString module = modules[i]; - kdDebug() << "Module: " << dir.absPath() + "/" + module << endl; - - if ( reQuery.search(module) != -1 ) - { - // strip the .la extension - module.truncate(module.length()-3); - KLibFactory *factory = KLibLoader::self()->factory(module.local8Bit()); - if ( factory ) - factory->create(); - else { - kdWarning() << "\tError loading " << module << " : " << KLibLoader::self()->lastErrorMessage() << endl; - ::exit( 1 ); - } - } - else - kdDebug() << "\tModule doesn't match." << endl; - } - } - - void Runner::setDebugCapturingEnabled(bool enabled) - { - s_debugCapturingEnabled = enabled; - } - - RegistryType &Runner::registry() - { - return m_registry; - } - - int Runner::numberOfTestCases() - { - return m_registry.count(); - } - - Runner *Runner::self() - { - if ( s_self == 0L ) s_self = new Runner(); - - return s_self; - } - - Runner::Runner() - { - reset(); - } - - int Runner::numberOfTests() const - { - return globalSteps; - } - - int Runner::numberOfPassedTests() const - { - return globalPasses; - } - - int Runner::numberOfFailedTests() const - { - return globalFails; - } - - int Runner::numberOfExpectedFailures() const - { - return globalXFails; - } - - int Runner::numberOfSkippedTests() const - { - return globalSkipped; - } - - void Runner::reset() - { - globalSteps = 0; - globalPasses = 0; - globalFails = 0; - globalXFails = 0; - globalXPasses = 0; - globalSkipped = 0; - } - - int Runner::runTests() - { - globalSteps = 0; - globalPasses = 0; - globalFails = 0; - globalXFails = 0; - globalXPasses = 0; - globalSkipped = 0; - - cout << "# Running normal tests... #" << endl << endl; - RegistryIteratorType it(m_registry); - - for( ; it.current(); ++it ) - runTest(it.currentKey()); - -#if 0 // very thorough, but not very readable - cout << "# Done with normal tests:" << endl; - cout << " Total test cases: " << m_registry.count() << endl; - cout << " Total test steps : " << globalSteps << endl; - cout << " Total passed test steps (including unexpected) : " << globalPasses << endl; - cout << " Total unexpected passed test steps : " << globalXPasses << endl; - cout << " Total failed test steps (including expected) : " << globalFails << endl; - cout << " Total expected failed test steps : " << globalXFails << endl; - cout << " Total skipped test steps : " << globalSkipped << endl; -#else - unsigned int numTests = m_registry.count(); // should this be globalSteps instead? - TQString str; - if ( globalFails == 0 ) - if ( globalXFails == 0 ) - str = TQString( "All %1 tests passed" ).arg( numTests ); - else - str = TQString( "All %1 tests behaved as expected (%2 expected failures)" ).arg( numTests ).arg( globalXFails ); - else - if ( globalXPasses == 0 ) - str = TQString( "%1 of %2 tests failed" ).arg( globalFails ).arg( numTests ); - else - str = TQString( "%1 of %2 tests did not behave as expected (%1 unexpected passes)" ).arg( globalFails ).arg( numTests ).arg( globalXPasses ); - if ( globalSkipped ) - str += TQString( " (%1 tests skipped)" ).arg( globalSkipped ); - cout << str.local8Bit().data() << endl; -#endif - - return m_registry.count(); - } - - void Runner::runMatchingTests(const TQString &prefix) - { - RegistryIteratorType it(m_registry); - for( ; it.current(); ++it ) - if ( TQString(it.currentKey()).startsWith(prefix) ) - runTest(it.currentKey()); - } - - void Runner::runTest(const char *name) - { - Tester *test = m_registry.find(name); - if ( test == 0L ) return; - - if ( s_debugCapturingEnabled ) - { - cout << "KUnitTest_Debug_Start[" << name << "]" << endl; - } - - test->results()->clear(); - test->allTests(); - - if ( s_debugCapturingEnabled ) - { - cout << "KUnitTest_Debug_End[" << name << "]" << endl << endl << flush; - } - - int numPass = 0; - int numFail = 0; - int numXFail = 0; - int numXPass = 0; - int numSkip = 0; - TQStringList xpassList; - TQStringList errorList; - TQStringList xfailList; - TQStringList skipList; - - if ( test->inherits("KUnitTest::SlotTester") ) - { - SlotTester *sltest = static_cast<SlotTester*>(test); - TestResultsListIteratorType it(sltest->resultsList()); - for ( ; it.current(); ++it) - { - numPass += it.current()->passed() + it.current()->xpasses(); - numFail += it.current()->errors() + it.current()->xfails(); - numXFail += it.current()->xfails(); - numXPass += it.current()->xpasses(); - numSkip += it.current()->skipped(); - globalSteps += it.current()->testsFinished(); - - xpassList += it.current()->xpassList(); - errorList += it.current()->errorList(); - xfailList += it.current()->xfailList(); - skipList += it.current()->skipList(); - } - } - else - { - numPass= test->results()->passed() + test->results()->xpasses(); - numFail= test->results()->errors() + test->results()->xfails(); - numXFail = test->results()->xfails(); - numXPass = test->results()->xpasses(); - numSkip= test->results()->skipped(); - globalSteps += test->results()->testsFinished(); - - xpassList += test->results()->xpassList(); - errorList += test->results()->errorList(); - xfailList += test->results()->xfailList(); - skipList += test->results()->skipList(); - } - - - globalPasses += numPass; - globalFails += numFail; - globalXFails += numXFail; - globalXPasses += numXPass; - globalSkipped += numSkip; - - cout << name << " - "; - cout << numPass << " test" << ( ( 1 == numPass )?"":"s") << " passed"; - if ( 0 < xpassList.count() ) { - cout << " (" << numXPass << " unexpected pass" << ( ( 1 == numXPass )?"":"es") << ")"; - } - cout << ", " << numFail << " test" << ( ( 1 == numFail )?"":"s") << " failed"; - if ( 0 < numXFail ) { - cout << " (" << numXFail << " expected failure" << ( ( 1 == numXFail )?"":"s") << ")"; - } - if ( 0 < numSkip ) { - cout << "; also " << numSkip << " skipped"; - } - cout << endl; - - if ( 0 < numXPass ) { - cout << " Unexpected pass" << ( ( 1 == numXPass )?"":"es") << ":" << endl; - TQStringList list = xpassList; - for ( TQStringList::Iterator itr = list.begin(); itr != list.end(); ++itr ) { - cout << "\t" << (*itr).latin1() << endl; - } - } - if ( 0 < (numFail - numXFail) ) { - cout << " Unexpected failure" << ( ( 1 == numFail )?"":"s") << ":" << endl; - TQStringList list = errorList; - for ( TQStringList::Iterator itr = list.begin(); itr != list.end(); ++itr ) { - cout << "\t" << (*itr).latin1() << endl; - } - } - if ( 0 < numXFail ) { - cout << " Expected failure" << ( ( 1 == numXFail)?"":"s") << ":" << endl; - TQStringList list = xfailList; - for ( TQStringList::Iterator itr = list.begin(); itr != list.end(); ++itr ) { - cout << "\t" << (*itr).latin1() << endl; - } - } - if ( 0 < numSkip ) { - cout << " Skipped test" << ( ( 1 == numSkip )?"":"s") << ":" << endl; - TQStringList list = skipList; - for ( TQStringList::Iterator itr = list.begin(); itr != list.end(); ++itr ) { - cout << "\t" << (*itr).latin1() << endl; - } - } - cout << endl; - - emit finished(name, test); - } -} - -#include "runner.moc" - diff --git a/kunittest/runner.h b/kunittest/runner.h deleted file mode 100644 index 5ed386b00..000000000 --- a/kunittest/runner.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * kunittest.h - * - * Copyright (C) 2004 Zack Rusin <zack@kde.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*! - * @file runner.h - * Defines a set of macros and classes for running unit tests - */ - -#ifndef KUNITTEST_RUNNER_H -#define KUNITTEST_RUNNER_H - -#include <iostream> -using namespace std; - -#include <tqobject.h> -#include <tqasciidict.h> -#include <tqstring.h> - -#include <tdelibs_export.h> - -#include "tester.h" - -class TQSocketNotifier; - -namespace KUnitTest -{ - /*! @def KUNITTEST_SUITE(suite) - * - * This macro must be used if you are not making a test-module. The macro - * defines the name of the test suite. - */ - #define KUNITTEST_SUITE(suite)\ - static const TQString s_kunittest_suite = suite; - - /*! @def KUNITTEST_REGISTER_TESTER( tester ) - * @brief Automatic registration of Tester classes. - * - * This macro can be used to register the Tester into the global registry. Use - * this macro in the implementation file of your Tester class. If you keep the - * Tester classes in a shared or convenience library then you should not use this - * macro as this macro relies on the static initialization of a TesterAutoregister class. - * You can always use the static Runner::registerTester(const char *name, Tester *test) method. - */ - #define KUNITTEST_REGISTER_TESTER( tester )\ - static TesterAutoregister tester##Autoregister( TQString(s_kunittest_suite + TQString("::") + TQString::fromLocal8Bit(#tester)).local8Bit() , new tester ()) - - #define KUNITTEST_REGISTER_NAMEDTESTER( name, tester )\ - static TesterAutoregister tester##Autoregister( TQString(s_kunittest_suite + TQString("::") + TQString::fromLocal8Bit(name)).local8Bit() , new tester ()) - - /*! The type of the registry. */ - typedef TQAsciiDict<Tester> RegistryType; - - /*! A type that can be used to iterate through the registry. */ - typedef TQAsciiDictIterator<Tester> RegistryIteratorType; - - /*! The Runner class holds a list of registered Tester classes and is able - * to run those test cases. The Runner class follows the singleton design - * pattern, which means that you can only have one Runner instance. This - * instance can be retrieved using the Runner::self() method. - * - * The registry is an object of type RegistryType, it is able to map the name - * of a test to a pointer to a Tester object. The registry is also a singleton - * and can be accessed via Runner::registry(). Since there is only one registry, - * which can be accessed at all times, test cases can be added without having to - * worry if a Runner instance is present or not. This allows for a design in which - * the KUnitTest library can be kept separate from the test case sources. Test cases - * (classes inheriting from Tester) can be added using the static - * registerTester(const char *name, Tester *test) method. Allthough most users - * will want to use the KUNITTEST_REGISTER_TESTER macro. - * - * @see KUNITTEST_REGISTER_TESTER - */ - class KUNITTEST_EXPORT Runner : public TQObject - { - Q_OBJECT - - public: - /*! Registers a test case. A registry will be automatically created if necessary. - * @param name The name of the test case. - * @param test A pointer to a Tester object. - */ - static void registerTester(const char *name, Tester *test); - - /*! @returns The registry holding all the Tester objects. - */ - RegistryType ®istry(); - - /*! @returns The global Runner instance. If necessary an instance will be created. - */ - static Runner *self(); - - /*! @returns The number of registered test cases. - */ - int numberOfTestCases(); - - /*! Load all modules found in the folder. - * @param folder The folder where to look for modules. - * @param query A regular expression. Only modules which match the query will be run. - */ - static void loadModules(const TQString &folder, const TQString &query); - - /*! The runner can spit out special debug messages needed by the Perl script: kunittest_debughelper. - * This script can attach the debug output of each suite to the results in the KUnitTest GUI. - * Not very useful for console minded developers, so this static method can be used to disable - * those debug messages. - * @param enabled If true the debug messages are enabled (default), otherwise they are disabled. - */ - static void setDebugCapturingEnabled(bool enabled); - - private: - RegistryType m_registry; - static Runner *s_self; - static bool s_debugCapturingEnabled; - - protected: - Runner(); - - public: - /*! @returns The number of finished tests. */ - int numberOfTests() const; - - /*! @returns The number of passed tests. */ - int numberOfPassedTests() const; - - /*! @returns The number of failed tests, this includes the number of expected failures. */ - int numberOfFailedTests() const; - - /*! @returns The number of failed tests which were expected. */ - int numberOfExpectedFailures() const; - - /*! @returns The number of skipped tests. */ - int numberOfSkippedTests() const; - - public slots: - /*! Call this slot to run all the registered tests. - * @returns The number of finished tests. - */ - int runTests(); - - /*! Call this slot to run a single test. - * @param name The name of the test case. This name has to correspond to the name - * that was used to register the test. If the KUNITTEST_REGISTER_TESTER macro was - * used to register the test case then this name is the class name. - */ - void runTest(const char *name); - - /*! Call this slot to run tests with names starting with prefix. - * @param prefix Only run tests starting with the string prefix. - */ - void runMatchingTests(const TQString &prefix); - - /*! Reset the Runner in order to prepare it to run one or more tests again. - */ - void reset(); - - signals: - /*! Emitted after a test is finished. - * @param name The name of the test. - * @param test A pointer to the Tester object. - */ - void finished(const char *name, Tester *test); - void invoke(); - - private: - void registerTests(); - - private: - int globalSteps; - int globalTests; - int globalPasses; - int globalFails; - int globalXFails; - int globalXPasses; - int globalSkipped; - }; - - /*! The TesterAutoregister is a helper class to allow the automatic registration - * of Tester classes. - */ - class TesterAutoregister - { - public: - /*! @param name A unique name that identifies the Tester class. - * @param test A pointer to a Tester object. - */ - TesterAutoregister(const char *name, Tester *test) - { - if ( test->name() == 0L ) test->setName(name); - Runner::registerTester(name, test); - } - }; - -} - -#endif diff --git a/kunittest/samplemodule.cpp b/kunittest/samplemodule.cpp deleted file mode 100644 index 390102c38..000000000 --- a/kunittest/samplemodule.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <kunittest/runner.h> -#include <kunittest/module.h> - -#include "samplemodule.h" - -using namespace KUnitTest; - -KUNITTEST_MODULE( kunittest_samplemodule, "Suite1" ); -KUNITTEST_MODULE_REGISTER_TESTER( SampleTester ); - -void SampleTester::allTests() -{ - int i = 2; - CHECK( i + 2, 4 ); -} diff --git a/kunittest/samplemodule.h b/kunittest/samplemodule.h deleted file mode 100644 index b5fd2bcd4..000000000 --- a/kunittest/samplemodule.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SAMPLETESTMODULE_H -#define SAMPLETESTMODULE_H - -#include "tester.h" -// Outside of tdelibs you would use: #include <kunittest/tester.h> - -class SampleTester : public KUnitTest::Tester -{ -public: - void allTests(); -}; - -#endif diff --git a/kunittest/tester.cpp b/kunittest/tester.cpp deleted file mode 100644 index 11a24e653..000000000 --- a/kunittest/tester.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <iostream> -using namespace std; - -#include <tqmetaobject.h> - -#include "tester.h" - -namespace KUnitTest -{ - SlotTester::SlotTester(const char *name) : Tester(name) - { - m_resultsList.setAutoDelete(true); - m_total = m_results; - } - - void SlotTester::invokeMember(const TQString &str) - { - TQString slotname = TQString::number(TQSLOT_CODE) + str; - connect(this, TQT_SIGNAL(invoke()), this, slotname.ascii()); - emit invoke(); - disconnect(this, TQT_SIGNAL(invoke()), this, slotname.ascii()); - } - - void SlotTester::allTests() - { - TQStrList allSlots = metaObject()->slotNames(); - - if ( allSlots.contains("setUp()") > 0 ) invokeMember("setUp()"); - - for ( char *sl = allSlots.first(); sl; sl = allSlots.next() ) - { - TQString str = sl; - - if ( str.startsWith("test") ) - { - m_results = results(sl); - m_results->clear(); - - cout << "KUnitTest_Debug_BeginSlot[" << sl << "]" << endl; - invokeMember(str); - cout << "KUnitTest_Debug_EndSlot[" << sl << "]" << endl; - } - } - - if ( allSlots.contains("tearDown()") > 0 ) invokeMember("tearDown()"); - - m_total->clear(); - } - - TestResults *SlotTester::results(const char *sl) - { - if ( m_resultsList.find(sl) == 0L ) m_resultsList.insert(sl, new TestResults()); - - return m_resultsList[sl]; - } -} - -TQTextStream& operator<<( TQTextStream& str, const TQRect& r ) { - str << "[" << r.x() << "," << r.y() << " - " << r.width() << "x" << r.height() << "]"; - return str; -} - -TQTextStream& operator<<( TQTextStream& str, const TQPoint& r ) { - str << "(" << r.x() << "," << r.y() << ")"; - return str; -} - -TQTextStream& operator<<( TQTextStream& str, const TQSize& r ) { - str << "[" << r.width() << "x" << r.height() << "]"; - return str; -} - -#include "tester.moc" - diff --git a/kunittest/tester.h b/kunittest/tester.h deleted file mode 100644 index e654b1b46..000000000 --- a/kunittest/tester.h +++ /dev/null @@ -1,716 +0,0 @@ -/* - * tester.h - * - * Copyright (C) 2004 Zack Rusin <zack@kde.org> - * Copyright (C) 2005 Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TESTER_H -#define TESTER_H - -/*! @mainpage KUnitTest - a UnitTest library for KDE - * - * @section contents Contents - * @li @ref background - * @li @ref usage - * @li @ref integration - * @li @ref module - * @li @ref advanced - * @li @ref scripts - * - * @section background Background - * - * KUnitTest is based on the "in reality no one wants to write tests and - * if it takes a lot of code no one will. So the less code to write the - * better" design principle. - * - * Copyright and credits: - * @li (C) 2004 Zack Rusin (original author) - * @li Brad Hards (import into CVS) - * @li (C) 2005 Jeroen Wijnhout (GUI, library, module) - * - * You are responsible for what you do with it though. It - * is licensed under a BSD license - read the top of each file. - * - * All the GUI related stuff is in tdesdk/kunittest, the core libraries are in tdelibs/kunittest. - * A simple example modules is in kdelisbs/kunittest/samplemodule.{h,cpp}, however more examples - * can be found in tdesdk/kunittest/example. - * - * There are roughly two ways to use the KUnitTest library. Either you create dynamically - * loadable modules and use the kunittestmodrunner or kunittestguimodrunner programs to run - * the tests, or you use the kunittest/kunittestgui library to create your own test runner - * application. - * - * The main parts of the KUnitTest library are: - * @li runner.{h,cpp} - it is the tester runner, holds all tests and runs - * them. - * @li runnergui.{h,cpp} - the GUI wrapper around the runner. The GUI neatly organizes the - * test results. With the kunittest helper script it can even add the debug output - * to the test results. For this you need to have the tdesdk module installed. - * @li tester.h - which holds the base of a pure test object (Tester). - * @li module.h - defines macros to create a dynamically loadable module. - * - * @section usage Example usage - * - * This section describes how to use the library to create your own tests and runner - * application. - * - * Now lets see how you would add a new test to KUnitTest. You do that by - * writting a Tester derived class which has an "allTests()" method: - * - * @code - * class SampleTest : public Tester - * { - * public: - * SampleTest(); - * - * void allTests(); - * }; - * @endcode - * - * Now in the allTests() method we implement our tests, which might look - * like: - * - * @code - * void SampleTest::allTests() - * { - * CHECK( 3+3, 6 ); - * CHECK( TQString( "hello%1" ).arg( " world not" ), TQString( "hello world" ) ); - * } - * @endcode - * - * CHECK() is implemented using a template, so you get type safe - * comparison. All that is needed is that the argument types have an - * @c operator==() defined. - * - * Now that you did that the only other thing to do is to tell the - * framework to add this test case, by using the KUNITTEST_REGISTER_TESTER(x) macro. Just - * put the following line in the implementation file: - * - * @code KUNITTEST_REGISTER_TESTER( SampleTest ); @endcode - * - * Note the ;, it is necessary. - * - * KUnitTest will do the rest. It will tell you which tests failed, how, what was the expected - * result, what was the result it got, what was the code that failed and so on. For example for - * the code above it would output: - * - * @verbatim -SampleTest - 1 test passed, 1 test failed - Unexpected failure: - sampletest.cpp[38]: failed on "TQString( "hello%1" ).arg( " world not" )" - result = 'hello world not', expected = 'hello world' -@endverbatim - * - * If you use the RunnerGUI class then you will be presented with a scrollable list of the - * test results. - * - * @section integration Integration - * - * The KUnitTest library is easy to use. Let's say that you have the tests written in the - * sampletest.h and sampletest.cpp files. Then all you need is a main.cpp file and a Makefile.am. - * You can copy both from the example file provided with the library. A typical main.cpp file - * looks like this: - * - * @code - * #include <kaboutdata.h> - * #include <kapplication.h> - * #include <kcmdlineargs.h> - * #include <kcmdlineargs.h> - * #include <klocale.h> - * #include <kunittest/runnergui.h> - * - * static const char description[] = I18N_NOOP("SampleTests"); - * static const char version[] = "0.1"; - * static KCmdLineOptions options[] = { KCmdLineLastOption }; - * - * int main( int argc, char** argv ) - * { - * TDEAboutData about("SampleTests", I18N_NOOP("SampleTests"), version, description, - * TDEAboutData::License_BSD, "(C) 2005 You!", 0, 0, "mail@provider"); - * - * TDECmdLineArgs::init(argc, argv, &about); - * TDECmdLineArgs::addCmdLineOptions( options ); - * TDEApplication app; - * - * KUnitTest::RunnerGUI runner(0); - * runner.show(); - * app.setMainWidget(&runner); - * - * return app.exec(); - * } - * @endcode - * - * The Makefile.am file will look like: - * - * @code - * INCLUDES = -I$(top_srcdir)/src $(all_includes) - * METASOURCES = AUTO - * check_PROGRAMS = sampletests - * sampletests_SOURCES = main.cpp sampletest.cpp - * sampletests_LDFLAGS = $(KDE_RPATH) $(all_libraries) - * sampletests_LDADD = -lkunittest - * noinst_HEADERS = sampletest.h - * - * check: - * kunittest $(top_builddir)/src/sampletests SampleTests - * @endcode - * - * Most of this Makefile.am will be self-explanatory. After running - * "make check" the binary "sampletests" will be built. The reason for - * adding the extra make target "check" is that you probably do not want - * to rebuild the test suite everytime you run make. - * - * You can run the binary on its own, but you get more functionality if you use - * the kunittest helper script. The Makefile.am is set up in such - * a way that this helper script is automatically run after you do a - * "make check". This scripts take two arguments, the first is the path - * to the binary to run. The second the application name, in this case SampleTests. - * This name is important since it is used to let the script communicate with the application - * via DCOP. The helper scripts relies on the Perl DCOP bindings, so these need to be installed. - * - * @section module Creating test modules - * - * If you think that writing your own test runner if too much work then you can also - * use the kunittestermodrunner application or the kunitguimodrunner script to run - * the tests for you. You do have to put your tests in a dynamically loadable module though. - * Fortunately KUnitTest comes with a few macros to help you do this. - * - * First the good news, you don't have to change the header file sampletest.h. However, we - * will rename it to samplemodule.h, so we remember we are making a module. The - * implementation file should be rename to samplemodule.cpp. This file requires some - * modifications. First we need to include the module.h header: - * - * @code - * #include <kunittest/module.h> - * @endcode - * - * This header file is needed because it defines some macro you'll need. In fact this is - * how you use them: - * - * @code - * KUNITTEST_MODULE( kunittest_samplemodule, "Tests for sample module" ); - * KUNITTEST_MODULE_REGISTER_TESTER( SimpleSampleTester ); - * KUNITTEST_MODULE_REGISTER_TESTER( SomeSampleTester ); - * @endcode - * - * The first macro, KUNITTEST_MODULE(), makes sure that the module can be loaded and that - * the test classes are created. The first argument "kunittest_samplemodule" is the library - * name, in this case the library we're creating a kunittest_samplemodule.la module. The - * second argument is name which will appear in the test runner for this test suite. - * - * The tester class are now added by the KUNITTEST_MODULE_REGISTER_TESTER() macro, not the - * KUNITTEST_REGISTER_TESTER(). The only difference between the two is that you have to - * pass the module class name to this macro. - * - * The Makefile.am is also a bit different, but not much: - * - * @code - * INCLUDES = -I$(top_srcdir)/include $(all_includes) - * METASOURCES = AUTO - * check_LTLIBRARIES = kunittest_samplemodule.la - * kunittest_samplemodule_la_SOURCES = samplemodule.cpp - * kunittest_samplemodule_la_LIBADD = $(LIB_KUNITTEST) - * kunittest_samplemodule_la_LDFLAGS = -module $(KDE_CHECK_PLUGIN) $(all_libraries) - * @endcode - * - * The $(KDE_CHECK_PLUGIN) macro is there to make sure a dynamically loadable - * module is created. - * - * After you have built the module you open a Konsole and cd into the build folder. Running - * the tests in the module is now as easy as: - * - * @code - * $ make check && kunittestmodrunner - * @endcode - * - * The kunittestmodrunner application loads all kunittest_*.la modules in the current - * directory. The exit code of this console application is the number of unexpected failures. - * - * If you want the GUI, you should use the kunittestmod script: - * - * @code - * $ make check && kunittestmod - * @endcode - * - * This script starts kunittestguimodrunner application and a helper script to take - * care of dealing with debug output. - * - * @section advanced Advanced usage - * - * Normally you just want to use CHECK(). If you are developing some more - * tests, and they are run (or not) based on some external dependency, - * you may need to skip some tests. In this case, rather than doing - * nothing (or worse, writing a test step that aborts the test run), you - * might want to use SKIP() to record that. Note that this is just a - * logging / reporting tool, so you just pass in a string: - * - * @code - * SKIP( "Test skipped because of lack of foo support." ); - * @endcode - * - * Similarly, you may have a test step that you know will fail, but you - * don't want to delete the test step (because it is showing a bug), but - * equally you can't fix it right now (eg it would break binary - * compatibility, or would violate a string freeze). In that case, it - * might help to use XFAIL(), for "expected failure". The test will still - * be run, and recorded as a failure (assuming it does fail), but will - * also be recorded separately. Usage might be as follows: - * - * @code - * XFAIL( 2+1, 4 ); - * @endcode - * - * You can mix CHECK(), SKIP() and XFAIL() within a single Tester derived - * class. - * - * - * @section exceptions Exceptions - * - * KUnitTest comes with simple support for testing whether an exception, such as a function call, - * throws an exception or not. Simply, for the usual macros there corresponding ones for - * exception testing: CHECK_EXCEPTION(), XFAIL_EXCEPTION(), and SKIP_EXCEPTION(). They all take two - * arguments: the expression that will catch the exception, and the expression that is supposed - * to throw the exception. - * - * For example: - * - * @code - * CHECK_EXCEPTION(EvilToothFairyException *, myFunction("I forgot to brush my teeth!")); - * @endcode - * - * @note The exception is not de-allocated in anyway. - * - * The macros does not allow introspection of the exceptions, such as testing a supplied - * identifier code on the exception object or similar; this requires manual coding, such - * as custom macros. - * - * @section scripts Scripts - * - * The library comes with several helper scripts: - * - * @li kunittest [app] [dcopobject] : Runs the application app and redirects all debug output to the dcopobject. - * @li kunittestmod --folder [folder] --query [query] : Loads and runs all modules in the folder matching the query. Use a GUI. - * @li kunittest_debughelper [dcopobject] : A PERL script that is able to redirect debug output to a RunnerGUI instance. - * - * These scripts are part of the tdesdk/kunittest module. - */ - -/*! - * @file tester.h - * Defines macros for unit testing as well as some test classes. - */ - -#include <iostream> -using namespace std; - -#include <tqobject.h> -#include <tqstringlist.h> -#include <tqasciidict.h> - -#include <tdelibs_export.h> - -/*! @def CHECK(x,y) - * Use this macro to perform an equality check. For example - * - * @code CHECK( numberOfErrors(), 0 ); @endcode - */ -#define CHECK( x, y ) check( __FILE__, __LINE__, #x, x, y, false ) - -/// for source-compat with qttestlib: use COMPARE(x,y) if you plan to port to qttestlib later. -#define COMPARE CHECK - -/// for source-compat with qttestlib: use VERIFY(x) if you plan to port to qttestlib later. -#define VERIFY( x ) CHECK( x, true ) - -/*! @def XFAIL(x,y) - * Use this macro to perform a check you expect to fail. For example - * - * @code XFAIL( numberOfErrors(), 1 ); @endcode - * - * If the test fails, it will be counted as such, however it will - * also be registered separately. - */ -#define XFAIL( x, y ) check( __FILE__, __LINE__, #x, x, y, true ) - -/*! @def SKIP(x) - * Use this macro to indicate that a test is skipped. - * - * @code SKIP("Test skipped because of lack of foo support."); @endcode - */ -#define SKIP( x ) skip( __FILE__, __LINE__, TQString::fromLatin1(#x)) - -/*! - * A macro testing that @p expression throws an exception that is catched - * with @p exceptionCatch. Use it to test that an expression, such as a function call, - * throws a certain exception. - * - * @note this macro assumes it's used in a function which is a sub-class of the Tester class. - */ -#define CHECK_EXCEPTION(exceptionCatch, expression) \ - try \ - { \ - expression; \ - } \ - catch(exceptionCatch) \ - { \ - setExceptionRaised(true); \ - } \ - if(exceptionRaised()) \ - { \ - success(TQString(__FILE__) + "[" + TQString::number(__LINE__) + "]: passed " + #expression); \ - } \ - else \ - { \ - failure(TQString(__FILE__) + "[" + TQString::number(__LINE__) + TQString("]: failed to throw " \ - "an exception on: ") + #expression); \ - } \ - setExceptionRaised(false); - -/*! - * This macro is similar to XFAIL, but is for exceptions instead. Flags @p expression - * as being expected to fail to throw an exception that @p exceptionCatch is supposed to catch. - */ -#define XFAIL_EXCEPTION(exceptionCatch, expression) \ - try \ - { \ - expression; \ - } \ - catch(exceptionCatch) \ - { \ - setExceptionRaised(true); \ - } \ - if(exceptionRaised()) \ - { \ - unexpectedSuccess(TQString(__FILE__) + "[" + TQString::number(__LINE__) + "]: unexpectedly threw an exception and passed: " + #expression); \ - }\ - else \ - { \ - expectedFailure(TQString(__FILE__) + "[" + TQString::number(__LINE__) + TQString("]: failed to throw an exception on: ") + #expression); \ - } \ - setExceptionRaised(false); - -/*! - * This macro is similar to SKIP, but is for exceptions instead. Skip testing @p expression - * and the @p exceptionCatch which is supposed to catch the exception, and register the test - * as being skipped. - */ -#define SKIP_EXCEPTION(exceptionCatch, expression) \ - skip( __FILE__, __LINE__, TQString("Exception catch: ")\ - .arg(TQString(#exceptionCatch)).arg(TQString(" Test expression: ")).arg(TQString(#expression))) - -/** - * Namespace for Unit testing classes - */ -namespace KUnitTest -{ - /*! A simple class that encapsulates a test result. A Tester class usually - * has a single TestResults instance associated with it, however the SlotTester - * class can have more TestResults instances (one for each test slot in fact). - */ - class KUNITTEST_EXPORT TestResults - { - friend class Tester; - - public: - TestResults() : m_tests( 0 ) {} - - virtual ~TestResults() {} - - /*! Clears the test results and debug info. Normally you do not need to call this. - */ - virtual void clear() - { - m_errorList.clear(); - m_xfailList.clear(); - m_xpassList.clear(); - m_skipList.clear(); - m_successList.clear(); - m_debug = ""; - m_tests = 0; - } - - /*! Add some debug info that can be view later. Normally you do not need to call this. - * @param debug The debug info. - */ - virtual void addDebugInfo(const TQString &debug) - { - m_debug += debug; - } - - /*! @returns The debug info that was added to this Tester object. - */ - TQString debugInfo() const { return m_debug; } - - /*! @returns The number of finished tests. */ - int testsFinished() const { return m_tests; } - - /*! @returns The number of failed tests. */ - int errors() const { return m_errorList.count(); } - - /*! @returns The number of expected failures. */ - int xfails() const { return m_xfailList.count(); } - - /*! @returns The number of unexpected successes. */ - int xpasses() const { return m_xpassList.count(); } - - /*! @returns The number of skipped tests. */ - int skipped() const { return m_skipList.count(); } - - /*! @returns The number of passed tests. */ - int passed() const { return m_successList.count(); } - - /*! @returns Details about the failed tests. */ - TQStringList errorList() const { return m_errorList; } - - /*! @returns Details about tests that failed expectedly. */ - TQStringList xfailList() const { return m_xfailList; } - - /*! @returns Details about tests that succeeded unexpectedly. */ - TQStringList xpassList() const { return m_xpassList; } - - /*! @returns Details about which tests were skipped. */ - TQStringList skipList() const { return m_skipList; } - - /*! @returns Details about the succeeded tests. */ - TQStringList successList() const { return m_successList; } - - private: - TQStringList m_errorList; - TQStringList m_xfailList; - TQStringList m_xpassList; - TQStringList m_skipList; - TQStringList m_successList; - TQString m_debug; - int m_tests; - }; - - typedef TQAsciiDict<TestResults> TestResultsListType; - - /*! A type that can be used to iterate through the registry. */ - typedef TQAsciiDictIterator<TestResults> TestResultsListIteratorType; - - /*! The abstract Tester class forms the base class for all test cases. Users must - * implement the void Tester::allTests() method. This method contains the actual test. - * - * Use the CHECK(x,y), XFAIL(x,y) and SKIP(x) macros in the allTests() method - * to perform the tests. - * - * @see CHECK, XFAIL, SKIP - */ - class KUNITTEST_EXPORT Tester : public TQObject - { - public: - Tester(const char *name = 0L) - : TQObject(0L, name), m_results(new TestResults()), m_exceptionState(false) - {} - - virtual ~Tester() { delete m_results; } - - public: - /*! Implement this method with the tests and checks you want to perform. - */ - virtual void allTests() = 0; - - public: - /*! @return The TestResults instance. - */ - virtual TestResults *results() { return m_results; } - - protected: - /*! This is called when the SKIP(x) macro is used. - * @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. - * @param line The linenumber in the file @p file. Use the __LINE__ macro for this. - * @param msg The message that identifies the skipped test. - */ - void skip( const char *file, int line, TQString msg ) - { - TQString skipEntry; - TQTextStream ts( &skipEntry, IO_WriteOnly ); - ts << file << "["<< line <<"]: " << msg; - skipTest( skipEntry ); - } - - /*! This is called when the CHECK or XFAIL macro is used. - * @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. - * @param line The linenumber in the file @p file. Use the __LINE__ macro for this. - * @param str The message that identifies the skipped test. - * @param result The result of the test. - * @param expectedResult The expected result. - * @param expectedFail Indicates whether or not a failure is expected. - */ - template<typename T> - void check( const char *file, int line, const char *str, - const T &result, const T &expectedResult, - bool expectedFail ) - { - cout << "check: " << file << "["<< line <<"]" << endl; - - if ( result != expectedResult ) - { - TQString error; - TQTextStream ts( &error, IO_WriteOnly ); - ts << file << "["<< line <<"]: failed on \"" << str - <<"\" result = '" << result << "' expected = '" << expectedResult << "'"; - - if ( expectedFail ) - expectedFailure( error ); - else - failure( error ); - - } - else - { - // then the test passed, but we want to record it if - // we were expecting a failure - if (expectedFail) - { - TQString err; - TQTextStream ts( &err, IO_WriteOnly ); - ts << file << "["<< line <<"]: " - <<" unexpectedly passed on \"" - << str <<"\""; - unexpectedSuccess( err ); - } - else - { - TQString succ; - TQTextStream ts( &succ, IO_WriteOnly ); - ts << file << "["<< line <<"]: " - <<" passed \"" - << str <<"\""; - success( succ ); - } - } - - ++m_results->m_tests; - } - - /*! - * This function can be used to flag succeeding tests, when - * doing customized tests while not using the check function. - * - * @param message the message describing what failed. Should be informative, - * such as mentioning the expression that failed and where, the file and file number. - */ - void success(const TQString &message) { m_results->m_successList.append(message); } - - /*! - * This function can be used to flag failing tests, when - * doing customized tests while not using the check function. - * - * @param message the message describing what failed. Should be informative, - * such as mentioning the expression that failed and where, the file name and file number. - */ - void failure(const TQString &message) { m_results->m_errorList.append(message); } - - /*! - * This function can be used to flag expected failures, when - * doing customized tests while not using the check function. - * - * @param message the message describing what failed. Should be informative, - * such as mentioning the expression that failed and where, the file name and file number. - */ - void expectedFailure(const TQString &message) { m_results->m_xfailList.append(message); } - - /*! - * This function can be used to flag unexpected successes, when - * doing customized tests while not using the check function. - * - * @param message the message describing what failed. Should be informative, - * such as mentioning the expression that failed and where, the file name and file number. - */ - void unexpectedSuccess(const TQString &message) { m_results->m_xpassList.append(message); } - - /*! - * This function can be used to flag a test as skipped, when - * doing customized tests while not using the check function. - * - * @param message the message describing what failed. Should be informative, - * such as mentioning the expression that failed and where, the file name and file number. - */ - void skipTest(const TQString &message) { m_results->m_skipList.append(message); } - - /*! - * exceptionRaised and exceptionState are book-keeping functions for testing for - * exceptions. setExceptionRaised sets an internal boolean to true. - * - * @see exceptionRaised - * @param state the new - */ - void setExceptionRaised(bool state) { m_exceptionState = state; } - - /*! - * Returns what the currently tested exception state. - * - * @see setExceptionRaised - */ - bool exceptionRaised() const - { - return m_exceptionState; - } - - protected: - TestResults *m_results; - - private: - - bool m_exceptionState; - }; - - /*! The SlotTester class is a special Tester class, one that will - * execute all slots that start with the string "test". The method - * void allTests() is implemented and should not be overriden. - */ - class KUNITTEST_EXPORT SlotTester : public Tester - { - Q_OBJECT - - public: - SlotTester(const char *name = 0L); - - void allTests(); - - TestResults *results(const char *sl); - - TestResultsListType &resultsList() { return m_resultsList; } - - signals: - void invoke(); - - private: - void invokeMember(const TQString &str); - - TestResultsListType m_resultsList; - TestResults *m_total; - }; -} - -KUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQRect& r ); - -KUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQPoint& r ); - -KUNITTEST_EXPORT TQTextStream& operator<<( TQTextStream& str, const TQSize& r ); - -#endif |