diff options
author | Baptiste Lepilleur <gaiacrtn@free.fr> | 2002-02-28 09:58:40 +0000 |
---|---|---|
committer | Baptiste Lepilleur <gaiacrtn@free.fr> | 2002-02-28 09:58:40 +0000 |
commit | 2c7af6bda8b090a31dd39e3ca6e5c55ed7758fb9 (patch) | |
tree | bab900654046a7afabcf534647be53ea1d4a90a3 | |
parent | 36905b4f9faf4075abfa1c695c443185650c47a2 (diff) | |
download | cppunit-2c7af6bda8b090a31dd39e3ca6e5c55ed7758fb9.tar.gz |
NEW: updated and restructured.
NEW: updated and restructured.
* include/cppunit/CompilerOutputter.h:
* src/cppunit/CompilerOutputter.cpp:
updated against TestResultChange. Changed TestResult to TestResultCollector.
* include/cppunit/extensions/HelperMacros.h: minor documentation fix.
* include/cppunit/Outputter.h: added. Abstract base class for all Outputter.
* include/cppunit/Portability.h: made the fix on OStringStream suggested by
Bob Summerwill to remove level 4 warning with VC++.
* include/cppunit/TestAssert.h: added macro CPPUNIT_ASSERT_EQUAL_MESSAGE.
* src/cppunit/TestFailure.cpp:
* include/cppunit/TestFailure.h: added method clone() to duplicate a failure. Made
all method virtual.
* include/cppunit/TestListener.h: changed signature of addFailure() to
addFailure( const TestFailure &failure ). Failure is now only a temporary object.
* include/cppunit/Outputter.h: added. Abstract base class for all outputter. Used
by TextTestRunner.
* include/cppunit/SynchronizedObject.h:
* src/cppunit/SynchronizedObject.cpp: added. Class extracted from TestResult.
Base class for objects that can be accessed from different threads.
* include/cppunit/TestResult.h: TestFailure.h is no longer included.
* include/cppunit/TestResult.h:
* src/cppunit/TestResult.cpp: extracted all methods related to keeping track
of the result to the new TestResultCollector class which is a TestListener.
* include/cppunit/TestResultCollector.h:
* src/cppunit/TestResultCollector.cpp: added. TestListener which kept track
of the result of the test run. All failure/error, and tests are tracked.
* include/cppunit/TestSucessListener.h:
* src/cppunit/TestSucessListener.cpp: added. TestListener extracted from
TestResult. Is responsible for wasSucessful().
* include/cppunit/TestCase.h:
* src/cppunit/TestCase.cpp: reindented.
* include/cppunit/TextOutputter.h:
* src/cppunit/TextOutputter.cpp: added. Copied from the deprecated
TextTestResult and modified to act as an Ouputter.
* include/cppunit/TextTestProgressListener.h:
* src/cppunit/TextTestProgressListener.cpp: Copied from the deprecated
TextTestResult and modified to print the dot while the test are running.
* include/cppunit/TextTestResult.h:
* src/cppunit/TextTestResult.cpp: updated against TestResult change.
No compatiblity break. Deprecated.
* include/cppunit/TextTestRunner.h:
* src/cppunit/TextTestRunner.cpp: updated to work with the new TestResult.
Use TextTestProgressListener and TextOutputter instead of TextTestResult.
Any outputter with interface Outputter can be used to print the test result
(CompilerOutputter, XmlOutputter, TextOutputter...)
* include/cppunit/XmlOutputter.h:
* src/cppunit/XmlOutputter.cpp: updated against TestResultChange.
Changed TestResult to TestResultCollector.
* src/msvc6/TestRunnerDlg.h:
* src/msvc6/TestRunnerDlg.cpp: fixed the 'fullrowselect' feature of the list view.
The dialog is a TestListener itself, it no longer use the GUITestResult class.
* src/msvc6/TestRunner.rc: moved the "autorun test button" in such a way that it
did not overlap the progress bar anymore.
* src/msvc6/MfcSynchronizationObject.h: added. Generic SynchronizedObject
lock for MFC.
* src/msvc6/GUITestResult.h :
* src/msvc6/GUITestResult.cpp : removed.
* src/qttestrunner/TestRunnerModel.h:
* src/qttestrunner/TestRunnerModel.cpp: changed addFailure() signature to reflect
change on TestListener.
* examples/cppunittest/CppUnitTestMain.cpp: updated to use the new Outputter
abstraction and TextTestRunner facilities.
* examples/cppunittest/FailingTestCase.h:
* examples/cppunittest/FailingTestCase.cpp: removed. Replaced by MockTestCase.
* examples/cppunittest/FailingTestCase.h:
* examples/cppunittest/FailingTestCase.h:
* examples/cppunittest/HelperMacrosTest.h:
* examples/cppunittest/HelperMacrosTest.cpp: Updated against TestResult change.
Use MockTestListener instead of TestResult to check for sucess or failure.
* examples/cppunittest/MockTestListener.h:
* examples/cppunittest/MockTestListener.cpp: the class now behave like a mock
object.
* examples/cppunittest/MockTestCase.h:
* examples/cppunittest/MockTestCase.cpp: added. Mock TestCase object.
* examples/cppunittest/OrthodoxTest.h:
* examples/cppunittest/OrthodoxTest.cpp: Updated against TestResult change.
Use MockTestListener instead of TestResult to check for sucess or failure.
* examples/cppunittest/SynchronizedTestResult.h: Updated against TestResult
change.
* examples/cppunittest/TestCallerTest.h:
* examples/cppunittest/TestCallerTest.cpp: Updated against TestResult change.
Use MockTestListener instead of TestResult.
* examples/cppunittest/TestCaseTest.h:
* examples/cppunittest/TestCaseTest.cpp: Updated against TestResult change.
Use MockTestListener and MockTestCase instead of FailingTestCase and TestResult.
* examples/cppunittest/TestDecoratorTest.h:
* examples/cppunittest/TestDecoratorTest.cpp: Updated against TestResult change.
Use MockTestCase instead of FailingTestCase.
* examples/cppunittest/TestListenerTest.h:
* examples/cppunittest/TestListenerTest.cpp: removed. Those unit tests have been
rewrote and moved to TestResultTest.
* examples/cppunittest/TestResultTest.h:
* examples/cppunittest/TestResultTest.cpp: Updated to test the new interface.
Tests from TestListenerTest have been moved here.
* examples/cppunittest/TestResultCollectorTest.h:
* examples/cppunittest/TestResultCollectorTest.cpp: added. Tests for the class
that been extracted from TestResult.
* examples/cppunittest/TestSetUpTest.h:
* examples/cppunittest/TestSetUpTest.cpp: renamed SetUp inner class to MockSetUp.
Changed interface to be more akin to a Mock object.
* examples/cppunittest/TestSuiteTest.h:
* examples/cppunittest/TestSuiteTest.cpp: Updated against TestResult change,
and rewrote to use MockTestCase instead of FailingTestCase.
* examples/cppunittest/XmlOutputterTest.h:
* examples/cppunittest/XmlOutputterTest.cpp: Updated against TestResult change.
Added some utility methods to make the update easier.
78 files changed, 2849 insertions, 1644 deletions
@@ -1,3 +1,153 @@ +2002-02-28 Baptiste Lepilleur <gaiacrtn@free.fr> + + * NEW: updated and restructured. + + * include/cppunit/CompilerOutputter.h: + * src/cppunit/CompilerOutputter.cpp: + updated against TestResultChange. Changed TestResult to TestResultCollector. + + * include/cppunit/extensions/HelperMacros.h: minor documentation fix. + + * include/cppunit/Outputter.h: added. Abstract base class for all Outputter. + + * include/cppunit/Portability.h: made the fix on OStringStream suggested by + Bob Summerwill to remove level 4 warning with VC++. + + * include/cppunit/TestAssert.h: added macro CPPUNIT_ASSERT_EQUAL_MESSAGE. + + * src/cppunit/TestFailure.cpp: + * include/cppunit/TestFailure.h: added method clone() to duplicate a failure. Made + all method virtual. + + * include/cppunit/TestListener.h: changed signature of addFailure() to + addFailure( const TestFailure &failure ). Failure is now only a temporary object. + + * include/cppunit/Outputter.h: added. Abstract base class for all outputter. Used + by TextTestRunner. + + * include/cppunit/SynchronizedObject.h: + * src/cppunit/SynchronizedObject.cpp: added. Class extracted from TestResult. + Base class for objects that can be accessed from different threads. + + * include/cppunit/TestResult.h: TestFailure.h is no longer included. + + * include/cppunit/TestResult.h: + * src/cppunit/TestResult.cpp: extracted all methods related to keeping track + of the result to the new TestResultCollector class which is a TestListener. + + * include/cppunit/TestResultCollector.h: + * src/cppunit/TestResultCollector.cpp: added. TestListener which kept track + of the result of the test run. All failure/error, and tests are tracked. + + * include/cppunit/TestSucessListener.h: + * src/cppunit/TestSucessListener.cpp: added. TestListener extracted from + TestResult. Is responsible for wasSucessful(). + + * include/cppunit/TestCase.h: + * src/cppunit/TestCase.cpp: reindented. + + * include/cppunit/TextOutputter.h: + * src/cppunit/TextOutputter.cpp: added. Copied from the deprecated + TextTestResult and modified to act as an Ouputter. + + * include/cppunit/TextTestProgressListener.h: + * src/cppunit/TextTestProgressListener.cpp: Copied from the deprecated + TextTestResult and modified to print the dot while the test are running. + + * include/cppunit/TextTestResult.h: + * src/cppunit/TextTestResult.cpp: updated against TestResult change. + No compatiblity break. Deprecated. + + * include/cppunit/TextTestRunner.h: + * src/cppunit/TextTestRunner.cpp: updated to work with the new TestResult. + Use TextTestProgressListener and TextOutputter instead of TextTestResult. + Any outputter with interface Outputter can be used to print the test result + (CompilerOutputter, XmlOutputter, TextOutputter...) + + * include/cppunit/XmlOutputter.h: + * src/cppunit/XmlOutputter.cpp: updated against TestResultChange. + Changed TestResult to TestResultCollector. + + * src/msvc6/TestRunnerDlg.h: + * src/msvc6/TestRunnerDlg.cpp: fixed the 'fullrowselect' feature of the list view. + The dialog is a TestListener itself, it no longer use the GUITestResult class. + + * src/msvc6/TestRunner.rc: moved the "autorun test button" in such a way that it + did not overlap the progress bar anymore. + + * src/msvc6/MfcSynchronizationObject.h: added. Generic SynchronizedObject + lock for MFC. + + * src/msvc6/GUITestResult.h : + * src/msvc6/GUITestResult.cpp : removed. + + * src/qttestrunner/TestRunnerModel.h: + * src/qttestrunner/TestRunnerModel.cpp: changed addFailure() signature to reflect + change on TestListener. + + * examples/cppunittest/CppUnitTestMain.cpp: updated to use the new Outputter + abstraction and TextTestRunner facilities. + + * examples/cppunittest/FailingTestCase.h: + * examples/cppunittest/FailingTestCase.cpp: removed. Replaced by MockTestCase. + + * examples/cppunittest/FailingTestCase.h: + * examples/cppunittest/FailingTestCase.h: + + * examples/cppunittest/HelperMacrosTest.h: + * examples/cppunittest/HelperMacrosTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult to check for sucess or failure. + + * examples/cppunittest/MockTestListener.h: + * examples/cppunittest/MockTestListener.cpp: the class now behave like a mock + object. + + * examples/cppunittest/MockTestCase.h: + * examples/cppunittest/MockTestCase.cpp: added. Mock TestCase object. + + * examples/cppunittest/OrthodoxTest.h: + * examples/cppunittest/OrthodoxTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult to check for sucess or failure. + + * examples/cppunittest/SynchronizedTestResult.h: Updated against TestResult + change. + + * examples/cppunittest/TestCallerTest.h: + * examples/cppunittest/TestCallerTest.cpp: Updated against TestResult change. + Use MockTestListener instead of TestResult. + + * examples/cppunittest/TestCaseTest.h: + * examples/cppunittest/TestCaseTest.cpp: Updated against TestResult change. + Use MockTestListener and MockTestCase instead of FailingTestCase and TestResult. + + * examples/cppunittest/TestDecoratorTest.h: + * examples/cppunittest/TestDecoratorTest.cpp: Updated against TestResult change. + Use MockTestCase instead of FailingTestCase. + + * examples/cppunittest/TestListenerTest.h: + * examples/cppunittest/TestListenerTest.cpp: removed. Those unit tests have been + rewrote and moved to TestResultTest. + + * examples/cppunittest/TestResultTest.h: + * examples/cppunittest/TestResultTest.cpp: Updated to test the new interface. + Tests from TestListenerTest have been moved here. + + * examples/cppunittest/TestResultCollectorTest.h: + * examples/cppunittest/TestResultCollectorTest.cpp: added. Tests for the class + that been extracted from TestResult. + + * examples/cppunittest/TestSetUpTest.h: + * examples/cppunittest/TestSetUpTest.cpp: renamed SetUp inner class to MockSetUp. + Changed interface to be more akin to a Mock object. + + * examples/cppunittest/TestSuiteTest.h: + * examples/cppunittest/TestSuiteTest.cpp: Updated against TestResult change, + and rewrote to use MockTestCase instead of FailingTestCase. + + * examples/cppunittest/XmlOutputterTest.h: + * examples/cppunittest/XmlOutputterTest.cpp: Updated against TestResult change. + Added some utility methods to make the update easier. + 2001-10-28 Steve M. Robbins <steve@nyongwa.montreal.qc.ca> * INSTALL-unix: Add note about cygwin. @@ -1,48 +1,87 @@ New in CppUnit 1.7.0 -------------------- -* New macros in HelperMacros.h: + In short: + - new facilities to write custom assertions + - new assertions + - new macros to define test case in your fixture + - registration of test fixture in named suite + - xml & compiler format test result output + - a new graphic test runner for the QT library + - MFC test runner window is resizable + - architecture clean-up: TestResultCollector extracted from TestResult. + +* New assertion (TestAssert.h): + + CPPUNIT_FAIL(message) : equivalent to CPPUNIT_ASSERT_MESSAGE( message, false ) + + CPPUNIT_ASSERT_EQUAL_MESSAGE( expectedValue, actualValue, additionalMessage ): + behave like CPPUNIT_ASSERT_EQUAL but allow to add some contextual information. + +* New macros to write test case (HelperMacros.h): CPPUNIT_TEST_EXCEPTION that expect an exception of a specified type to be thrown. CPPUNIT_TEST_FAIL that expect a test to fail. - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION to register a suite in a named suite. + CPPUNIT_TEST_SUITE_NAMED_REGISTRATION to register a suite in a named suite. See + cppunittest example for a demo. -* Fail with arbitrary message: CPPUNIT_FAIL +* TextTestRunner (TextTestRunner.h): + -run() returns a boolean indicating is the run was sucessful. + -the constructor and setOutputter() allow you do define a specific outputter + to print the test result (CompilerOutputter, TextOutputter, XmlOutputter...) + -result() provide access to the result of the test run. + -eventManager() give access to the TestResult, allowing you to register others + TestListener. -* NotEqualException constructor take an additional message (usually used to -point out where the difference occured between the expected and actual value) -that can be retreived with additionalMessage(). See Asserter documentation for -an example of usage. +* TestResult (TestResult.h): + - That class has been splitted in two: TestResult and TestResultCollector. + + - TestResult manages the TestListener (registration and event dispatch), as + well as the stop flag indicating if the current test run should be interrupted. + All other responsabilites have been moved to TestResultCollector. -* TextTestRunner now return a boolean indicating is the run was sucessful. You -can also specify a TextTestResult in the constructor and access the result -with result(). + - TestResult no longer hold the result of the test run (this is done by + TestResultCollector which is a TestListener). -* Helpers to construct your own assertion +* TestListener (TestListener.h): + - all failures and errors are reported using a single method: + virtual void addFailure( const TestFailure &failure ) + => the failure object life time is limited to that of the method call. + Use TestFailure::isError() to distinguish error from failure. + Use TestFailure::clone() to obtain a duplicate of the failure. + +* New helpers to construct your own assertion (Asserter.h): It is now very easy to create your own assertion macro with failure location. - CPPUNIT_SOURCELINE() macro have been added. It capture the failure location - in a SourceLine object. + Asserter namespace contains functions used to construct and throw exception + to report failure. See Asserter documentation for an example of usage, and + examples/cppunittest/XmlUniformiser.h for a real life example. + + CPPUNIT_SOURCELINE() macro have been added (SourceLine.h). It captures the + failure location in a SourceLine object. Use it to write your own macros. Asserter namespace contains functions used to construct and throw exception - to report failure. See Asserter documentation for an example of usage. + to report failure. See Asserter documentation for an example of usage, and + examples/cppunittest/XmlUniformiser.h for a real life example. -* TestRunner +* TestListener (TestListener.h): - - Qt TestRunner : a test runner for the Qt library (http://www.trolltech.com). - See examples/qt for an example of use. + - TestSucesssListener : a simple listener that checks if a test has failed. - - MFC TestRunner : the dialog can now be resized. List view column sizes, - as well as the dialog size, are saved. + - TestResultCollector : store all the test result. This class has been + extracted from the hold TestResult class. + + - TextTestProgressListener : print dot on cout to each time a test ends. + Letter 'F' and 'E' are printed when a failure or an error occurs. -* Output +* Output (Outputter.h): - - XML output : You can dump the TestResult as an XML document using + - XML output: You can dump the TestResult as an XML document using XmlOutputter. See examples/cppunittest/XmlOutputterTest.cpp for document structure and usage. @@ -50,8 +89,27 @@ with result(). compiler compatible format. You can use your IDE to jump to the first failure. See examples/cppunittest/CppUniTestMain.cpp for an example of usage. + - Text output : replace the deprecated TextTestResult. Print the result in + a human readable format. + +* NotEqualException constructor take an additional message (usually used to +point out where the difference occured between the expected and actual value) +that can be retreived with additionalMessage(). See Asserter documentation for +an example of usage. + +* TestRunner + + - Qt TestRunner : a test runner for the Qt library (http://www.trolltech.com). + See examples/qt for an example of use. + + - MFC TestRunner : the dialog can now be resized. List view column sizes, + as well as the dialog size, are saved. + * Deprecated + - TextTestResult : use the test listener TextTestProgressListener and the + ouputter TextOuputter instead. + - Methods having fileName, lineNumber as parameter. Usually replaced by a similar method that take a SourceLine parameter. Exception and TestAssert are impacted. @@ -62,11 +120,17 @@ with result(). and throwing as been moved to Asserter namespace. * Compatibility break: + + TestResult has been splitted in two class. TestResultCollector compatibility + breaks refer to the methods that were previously in TestResult. + - TestListener::addError() was removed. addFailure() is used to report any kind of failure. - - TestResult::errors() was removed. Use failures() instead. - - TestResult::failures() now reports all kind of failures. - - TestResult::failures() returns a const reference. + - TestResultCollector::errors() was removed. Use failures() instead. + - TestResultCollector::failures() now reports all kind of failures. + - TestResultCollector::failures() returns a const reference. + - void TestListener::addFailure( TestFailure *failure ) was removed. + - void TestListener::addError( TestFailure *failure ) signature changed. * Bug fix: - test ExceptionTest.testAssignment() don't fail anymore on VC++. See FAQ @@ -13,4 +13,5 @@ forthcoming assertEquals() to make comparison easier, - source file location. - +* BugFix: CompilerOutputter::wrap(), bug when wrapping empty line in the middle +of a text (they disappear). diff --git a/examples/cppunittest/CppUnitTestMain.cpp b/examples/cppunittest/CppUnitTestMain.cpp index 7c8fba8..2a26ab2 100644 --- a/examples/cppunittest/CppUnitTestMain.cpp +++ b/examples/cppunittest/CppUnitTestMain.cpp @@ -1,6 +1,6 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/CompilerOutputter.h> -#include <cppunit/TextTestResult.h> +#include <cppunit/TestResultCollector.h> #include <cppunit/TextTestRunner.h> #include "CppUnitTestSuite.h" @@ -8,22 +8,26 @@ int main( int argc, char* argv[] ) { + // if command line contains "-selftest" then this is the post build check + // => the output must be in the compiler error format. bool selfTest = (argc > 1) && (std::string("-selftest") == argv[1]); CppUnit::TextTestRunner runner; - runner.addTest( CppUnitTest::suite() ); + runner.addTest( CppUnitTest::suite() ); // Add the top suite to the test runner - bool wasSucessful = runner.run( "", false, !selfTest ); if ( selfTest ) - { - CppUnit::CompilerOutputter *outputter = - CppUnit::CompilerOutputter::defaultOutputter( runner.result(), - std::cerr ); - outputter->write(); - delete outputter; + { // Change the default outputter to a compiler error format outputter + // The test runner owns the new outputter. + runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( + &runner.result(), + std::cerr ) ); } + // Run the test and don't wait a key if post build check. + bool wasSucessful = runner.run( "", !selfTest ); + + // Return error code 1 if the one of test failed. return wasSucessful ? 0 : 1; } diff --git a/examples/cppunittest/CppUnitTestMain.dsp b/examples/cppunittest/CppUnitTestMain.dsp index 6045662..aac308b 100644 --- a/examples/cppunittest/CppUnitTestMain.dsp +++ b/examples/cppunittest/CppUnitTestMain.dsp @@ -131,209 +131,220 @@ PostBuild_Cmds=$(TargetPath) -selftest # Name "CppUnitTestMain - Win32 Release" # Name "CppUnitTestMain - Win32 Debug" # Name "CppUnitTestMain - Win32 Debug Crossplatform Setting" +# Begin Group "Suite" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\BaseTestCase.cpp +SOURCE=.\CoreSuite.h # End Source File # Begin Source File -SOURCE=.\BaseTestCase.h +SOURCE=.\CppUnitTestSuite.cpp # End Source File # Begin Source File -SOURCE=.\CoreSuite.h +SOURCE=.\CppUnitTestSuite.h # End Source File # Begin Source File -SOURCE=.\CppUnitTestMain.cpp +SOURCE=.\ExtensionSuite.h # End Source File # Begin Source File -SOURCE=.\CppUnitTestSuite.cpp +SOURCE=.\HelperSuite.h # End Source File # Begin Source File -SOURCE=.\CppUnitTestSuite.h +SOURCE=.\OutputSuite.h # End Source File # Begin Source File -SOURCE=.\ExceptionTest.cpp +SOURCE=.\UnitTestToolSuite.h # End Source File +# End Group +# Begin Group "Tests" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\ExceptionTest.h +SOURCE=.\ExceptionTest.cpp # End Source File # Begin Source File -SOURCE=.\ExtensionSuite.h +SOURCE=.\ExceptionTest.h # End Source File # Begin Source File -SOURCE=.\FailingTestCase.cpp +SOURCE=.\HelperMacrosTest.cpp # End Source File # Begin Source File -SOURCE=.\FailingTestCase.h +SOURCE=.\HelperMacrosTest.h # End Source File # Begin Source File -SOURCE=.\FailureException.h +SOURCE=.\NotEqualExceptionTest.cpp # End Source File # Begin Source File -SOURCE=.\HelperMacrosTest.cpp +SOURCE=.\NotEqualExceptionTest.h # End Source File # Begin Source File -SOURCE=.\HelperMacrosTest.h +SOURCE=.\OrthodoxTest.cpp # End Source File # Begin Source File -SOURCE=.\HelperSuite.h +SOURCE=.\OrthodoxTest.h # End Source File # Begin Source File -SOURCE=.\Makefile.am +SOURCE=.\RepeatedTestTest.cpp # End Source File # Begin Source File -SOURCE=.\MockTestListener.cpp +SOURCE=.\RepeatedTestTest.h # End Source File # Begin Source File -SOURCE=.\MockTestListener.h +SOURCE=.\TestAssertTest.cpp # End Source File # Begin Source File -SOURCE=.\NotEqualExceptionTest.cpp +SOURCE=.\TestAssertTest.h # End Source File # Begin Source File -SOURCE=.\NotEqualExceptionTest.h +SOURCE=.\TestCallerTest.cpp # End Source File # Begin Source File -SOURCE=.\OrthodoxTest.cpp +SOURCE=.\TestCallerTest.h # End Source File # Begin Source File -SOURCE=.\OrthodoxTest.h +SOURCE=.\TestCaseTest.cpp # End Source File # Begin Source File -SOURCE=.\OutputSuite.h +SOURCE=.\TestCaseTest.h # End Source File # Begin Source File -SOURCE=.\RepeatedTestTest.cpp +SOURCE=.\TestDecoratorTest.cpp # End Source File # Begin Source File -SOURCE=.\RepeatedTestTest.h +SOURCE=.\TestDecoratorTest.h # End Source File # Begin Source File -SOURCE=.\SubclassedTestCase.cpp +SOURCE=.\TestFailureTest.cpp # End Source File # Begin Source File -SOURCE=.\SubclassedTestCase.h +SOURCE=.\TestFailureTest.h # End Source File # Begin Source File -SOURCE=.\SynchronizedTestResult.h +SOURCE=.\TestResultCollectorTest.cpp # End Source File # Begin Source File -SOURCE=.\TestAssertTest.cpp +SOURCE=.\TestResultCollectorTest.h # End Source File # Begin Source File -SOURCE=.\TestAssertTest.h +SOURCE=.\TestResultTest.cpp # End Source File # Begin Source File -SOURCE=.\TestCallerTest.cpp +SOURCE=.\TestResultTest.h # End Source File # Begin Source File -SOURCE=.\TestCallerTest.h +SOURCE=.\TestSetupTest.cpp # End Source File # Begin Source File -SOURCE=.\TestCaseTest.cpp +SOURCE=.\TestSetupTest.h # End Source File # Begin Source File -SOURCE=.\TestCaseTest.h +SOURCE=.\TestSuiteTest.cpp # End Source File # Begin Source File -SOURCE=.\TestDecoratorTest.cpp +SOURCE=.\TestSuiteTest.h # End Source File # Begin Source File -SOURCE=.\TestDecoratorTest.h +SOURCE=.\XmlOutputterTest.cpp # End Source File # Begin Source File -SOURCE=.\TestFailureTest.cpp +SOURCE=.\XmlOutputterTest.h # End Source File # Begin Source File -SOURCE=.\TestFailureTest.h +SOURCE=.\XmlUniformiserTest.cpp # End Source File # Begin Source File -SOURCE=.\TestListenerTest.cpp +SOURCE=.\XmlUniformiserTest.h # End Source File +# End Group +# Begin Group "Support" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\TestListenerTest.h +SOURCE=.\BaseTestCase.cpp # End Source File # Begin Source File -SOURCE=.\TestResultTest.cpp +SOURCE=.\BaseTestCase.h # End Source File # Begin Source File -SOURCE=.\TestResultTest.h +SOURCE=.\FailureException.h # End Source File # Begin Source File -SOURCE=.\TestSetupTest.cpp +SOURCE=.\MockTestCase.cpp # End Source File # Begin Source File -SOURCE=.\TestSetupTest.h +SOURCE=.\MockTestCase.h # End Source File # Begin Source File -SOURCE=.\TestSuiteTest.cpp +SOURCE=.\MockTestListener.cpp # End Source File # Begin Source File -SOURCE=.\TestSuiteTest.h +SOURCE=.\MockTestListener.h # End Source File # Begin Source File -SOURCE=.\TrackedTestCase.cpp +SOURCE=.\SubclassedTestCase.cpp # End Source File # Begin Source File -SOURCE=.\TrackedTestCase.h +SOURCE=.\SubclassedTestCase.h # End Source File # Begin Source File -SOURCE=.\UnitTestToolSuite.h +SOURCE=.\SynchronizedTestResult.h # End Source File # Begin Source File -SOURCE=.\XmlOutputterTest.cpp +SOURCE=.\TrackedTestCase.cpp # End Source File # Begin Source File -SOURCE=.\XmlOutputterTest.h +SOURCE=.\TrackedTestCase.h # End Source File # Begin Source File @@ -343,13 +354,14 @@ SOURCE=.\XmlUniformiser.cpp SOURCE=.\XmlUniformiser.h # End Source File +# End Group # Begin Source File -SOURCE=.\XmlUniformiserTest.cpp +SOURCE=.\CppUnitTestMain.cpp # End Source File # Begin Source File -SOURCE=.\XmlUniformiserTest.h +SOURCE=.\Makefile.am # End Source File # End Target # End Project diff --git a/examples/cppunittest/FailingTestCase.cpp b/examples/cppunittest/FailingTestCase.cpp deleted file mode 100644 index f519438..0000000 --- a/examples/cppunittest/FailingTestCase.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "FailingTestCase.h" - - -FailingTestCase::FailingTestCase( bool failSetUp, - bool failRunTest, - bool failTearDown ) : - CppUnit::TestCase( "FailingTestCase" ), - m_failSetUp( failSetUp ), - m_failRunTest( failRunTest ), - m_failTearDown( failTearDown ), - m_setUpCalled( false ), - m_runTestCalled( false ), - m_tearDownCalled( false ) -{ -} - - -FailingTestCase::~FailingTestCase() -{ -} - - -void -FailingTestCase::setUp() -{ - m_setUpCalled = true; - doFailure( m_failSetUp ); -} - - -void -FailingTestCase::tearDown() -{ - m_tearDownCalled = true; - doFailure( m_failTearDown ); -} - - -void -FailingTestCase::runTest() -{ - m_runTestCalled = true; - doFailure( m_failRunTest ); -} - - -void -FailingTestCase::doFailure( bool shouldFail ) -{ - if ( shouldFail ) - throw FailureException(); -} - - -void -FailingTestCase::verify( bool runTestCalled, - bool tearDownCalled ) -{ - CPPUNIT_ASSERT( m_setUpCalled ); - CPPUNIT_ASSERT_EQUAL( runTestCalled, m_runTestCalled ); - CPPUNIT_ASSERT_EQUAL( tearDownCalled, m_tearDownCalled ); -} diff --git a/examples/cppunittest/FailingTestCase.h b/examples/cppunittest/FailingTestCase.h deleted file mode 100644 index 2ac52b5..0000000 --- a/examples/cppunittest/FailingTestCase.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef FAILINGTESTCASE_H -#define FAILINGTESTCASE_H - -#include <cppunit/TestCase.h> -#include "FailureException.h" - - -class FailingTestCase : public CppUnit::TestCase -{ -public: - FailingTestCase( bool failSetUp =false, - bool failRunTest =false, - bool failTearDown =false ); - - virtual ~FailingTestCase(); - - virtual void setUp(); - virtual void tearDown(); - - virtual void runTest(); - - void verify( bool runTestCalled =true, - bool tearDownCalled =true); - -private: - FailingTestCase( const FailingTestCase © ); - void operator =( const FailingTestCase © ); - - void doFailure( bool shouldFail ); - -private: - bool m_failSetUp; - bool m_failRunTest; - bool m_failTearDown; - - bool m_setUpCalled; - bool m_runTestCalled; - bool m_tearDownCalled; -}; - - -#endif // FAILINGTESTCASE_H diff --git a/examples/cppunittest/HelperMacrosTest.cpp b/examples/cppunittest/HelperMacrosTest.cpp index 362bb7e..158715e 100644 --- a/examples/cppunittest/HelperMacrosTest.cpp +++ b/examples/cppunittest/HelperMacrosTest.cpp @@ -78,7 +78,9 @@ HelperMacrosTest::~HelperMacrosTest() void HelperMacrosTest::setUp() { + m_testListener = new MockTestListener( "mock-testlistener" ); m_result = new CppUnit::TestResult(); + m_result->addListener( m_testListener ); } @@ -86,6 +88,7 @@ void HelperMacrosTest::tearDown() { delete m_result; + delete m_testListener; } @@ -94,9 +97,11 @@ HelperMacrosTest::testNoSubclassing() { std::auto_ptr<CppUnit::TestSuite> suite( BaseTestCase::suite() ); CPPUNIT_ASSERT_EQUAL( 1, suite->countTestCases() ); + m_testListener->setExpectedStartTestCall( 1 ); + m_testListener->setExpectNoFailure(); suite->run( m_result ); - checkTestResult( 0,0,1 ); + m_testListener->verify(); } @@ -105,9 +110,11 @@ HelperMacrosTest::testSubclassing() { std::auto_ptr<CppUnit::TestSuite> suite( SubclassedTestCase::suite() ); CPPUNIT_ASSERT_EQUAL( 2, suite->countTestCases() ); + m_testListener->setExpectedStartTestCall( 2 ); + m_testListener->setExpectedAddFailureCall( 1 ); suite->run( m_result ); - checkTestResult( 1,0,2 ); + m_testListener->verify(); } @@ -115,8 +122,11 @@ void HelperMacrosTest::testFail() { std::auto_ptr<CppUnit::TestSuite> suite( FailTestCase::suite() ); + m_testListener->setExpectedStartTestCall( 1 ); + m_testListener->setExpectNoFailure(); + suite->run( m_result ); - checkTestResult( 0,0,1 ); + m_testListener->verify(); } @@ -124,8 +134,11 @@ void HelperMacrosTest::testFailToFail() { std::auto_ptr<CppUnit::TestSuite> suite( FailToFailTestCase::suite() ); + m_testListener->setExpectedStartTestCall( 1 ); + m_testListener->setExpectedAddFailureCall( 1 ); + suite->run( m_result ); - checkTestResult( 1,0,1 ); + m_testListener->verify(); } @@ -133,8 +146,11 @@ void HelperMacrosTest::testException() { std::auto_ptr<CppUnit::TestSuite> suite( ExceptionTestCase::suite() ); + m_testListener->setExpectedStartTestCall( 1 ); + m_testListener->setExpectNoFailure(); + suite->run( m_result ); - checkTestResult( 0,0,1 ); + m_testListener->verify(); } @@ -142,17 +158,9 @@ void HelperMacrosTest::testExceptionNotCaught() { std::auto_ptr<CppUnit::TestSuite> suite( ExceptionNotCaughtTestCase::suite() ); - suite->run( m_result ); - checkTestResult( 1,0,1 ); -} + m_testListener->setExpectedStartTestCall( 1 ); + m_testListener->setExpectedAddFailureCall( 1 ); - -void -HelperMacrosTest::checkTestResult( int expectedFailures, - int expectedErrors, - int expectedTestsRun ) -{ - CPPUNIT_ASSERT_EQUAL( expectedFailures, m_result->testFailures() ); - CPPUNIT_ASSERT_EQUAL( expectedErrors, m_result->testErrors() ); - CPPUNIT_ASSERT_EQUAL( expectedTestsRun, m_result->runTests() ); + suite->run( m_result ); + m_testListener->verify(); } diff --git a/examples/cppunittest/HelperMacrosTest.h b/examples/cppunittest/HelperMacrosTest.h index 44eb5f1..adb05c7 100644 --- a/examples/cppunittest/HelperMacrosTest.h +++ b/examples/cppunittest/HelperMacrosTest.h @@ -2,6 +2,7 @@ #define HELPERMACROSTEST_H #include <cppunit/extensions/HelperMacros.h> +#include "MockTestListener.h" class HelperMacrosTest : public CppUnit::TestCase @@ -36,12 +37,9 @@ private: HelperMacrosTest( const HelperMacrosTest © ); void operator =( const HelperMacrosTest © ); - void checkTestResult( int expectedFailures, - int expectedErrors, - int expectedTestsRun ); - private: CppUnit::TestResult *m_result; + MockTestListener *m_testListener; }; diff --git a/examples/cppunittest/Makefile.am b/examples/cppunittest/Makefile.am index 0850f6a..8903c62 100644 --- a/examples/cppunittest/Makefile.am +++ b/examples/cppunittest/Makefile.am @@ -15,12 +15,12 @@ cppunittestmain_SOURCES = \ ExceptionTest.cpp \ ExceptionTest.h \ ExtensionSuite.h \ - FailingTestCase.cpp \ - FailingTestCase.h \ FailureException.h \ HelperMacrosTest.cpp \ HelperMacrosTest.h \ HelperSuite.h \ + MockTestCase.h \ + MockTestCase.cpp \ MockTestListener.cpp \ MockTestListener.h \ NotEqualExceptionTest.cpp \ @@ -41,10 +41,10 @@ cppunittestmain_SOURCES = \ TestCaseTest.h \ TestDecoratorTest.cpp \ TestDecoratorTest.h \ - TestListenerTest.cpp \ - TestListenerTest.h \ TestFailureTest.cpp \ TestFailureTest.h \ + TestResultCollectorTest.cpp \ + TestResultCollectorTest.h \ TestResultTest.cpp \ TestResultTest.h \ TestSetUpTest.cpp \ diff --git a/examples/cppunittest/MockTestCase.cpp b/examples/cppunittest/MockTestCase.cpp new file mode 100644 index 0000000..6749272 --- /dev/null +++ b/examples/cppunittest/MockTestCase.cpp @@ -0,0 +1,173 @@ +#include "FailureException.h" +#include "MockTestCase.h" + + +MockTestCase::MockTestCase( std::string name ) + : CppUnit::TestCase( name ) + , m_hasSetUpExpectation( false ) + , m_expectedSetUpCall( 0 ) + , m_actualSetUpCall( 0 ) + , m_hasTearDownExpectation( false ) + , m_expectedTearDownCall( 0 ) + , m_actualTearDownCall( 0 ) + , m_expectRunTestCall( false ) + , m_expectedRunTestCallCount( 0 ) + , m_actualRunTestCallCount( 0 ) + , m_expectCountTestCasesCall( false ) + , m_expectedCountTestCasesCallCount( 0 ) + , m_actualCountTestCasesCallCount( 0 ) + , m_setUpThrow( false ) + , m_tearDownThrow( false ) + , m_runTestThrow( false ) +{ +} + + +MockTestCase::~MockTestCase() +{ +} + + +int +MockTestCase::countTestCases() const +{ + ++m_actualCountTestCasesCallCount; + if ( m_expectCountTestCasesCall ) + { + CPPUNIT_ASSERT_MESSAGE( getName() + ": unexpected MockTestCase::countTestCases() call", + m_actualCountTestCasesCallCount <= m_expectedCountTestCasesCallCount ); + } + + return SuperClass::countTestCases(); +} + + +void +MockTestCase::setUp() +{ + if ( m_hasSetUpExpectation ) + { + ++m_actualSetUpCall; + CPPUNIT_ASSERT_MESSAGE( getName() + ": unexpected MockTestCase::setUp() call", + m_actualSetUpCall <= m_expectedSetUpCall ); + } + + if ( m_setUpThrow ) + throw FailureException(); +} + +void +MockTestCase::tearDown() +{ + if ( m_hasTearDownExpectation ) + { + ++m_actualTearDownCall; + CPPUNIT_ASSERT_MESSAGE( getName() + ": unexpected MockTestCase::tearDown() call", + m_actualTearDownCall <= m_expectedTearDownCall ); + } + + if ( m_tearDownThrow ) + throw FailureException(); +} + + +void +MockTestCase::runTest() +{ + ++m_actualRunTestCallCount; + if ( m_expectRunTestCall ) + { + CPPUNIT_ASSERT_MESSAGE( getName() + ": unexpected MockTestCase::runTest() call", + m_actualRunTestCallCount <= m_expectedRunTestCallCount ); + } + + if ( m_runTestThrow ) + throw FailureException(); +} + + +void +MockTestCase::setExpectedSetUpCall( int callCount ) +{ + m_hasSetUpExpectation = true; + m_expectedSetUpCall = callCount; +} + + +void +MockTestCase::setExpectedTearDownCall( int callCount ) +{ +} + + +void +MockTestCase::setExpectedRunTestCall( int callCount ) +{ + m_expectRunTestCall = true; + m_expectedRunTestCallCount = callCount ; +} + + +void +MockTestCase::setExpectedCountTestCasesCall( int callCount ) +{ + m_expectCountTestCasesCall = true; + m_expectedCountTestCasesCallCount = callCount; +} + + +void +MockTestCase::makeSetUpThrow() +{ + m_setUpThrow = true; +} + + +void +MockTestCase::makeTearDownThrow() +{ + m_tearDownThrow = true; +} + + +void +MockTestCase::makeRunTestThrow() +{ + m_runTestThrow = true; +} + + +void +MockTestCase::verify() +{ + if ( m_hasSetUpExpectation ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedSetUpCall, + m_actualSetUpCall, + getName() + ": bad MockTestCase::setUp() " + "call count" ); + } + + if ( m_hasTearDownExpectation ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedTearDownCall, + m_actualTearDownCall, + getName() + ": bad MockTestCase::setUp() " + "call count" ); + } + + if ( m_expectCountTestCasesCall ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedCountTestCasesCallCount, + m_actualCountTestCasesCallCount, + getName() + ": bad MockTestCase::countTestCases() " + "call count" ); + } + if ( m_expectRunTestCall ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedRunTestCallCount, + m_actualRunTestCallCount, + getName() + ": bad MockTestCase::runTest() " + "call count" ); + } +} diff --git a/examples/cppunittest/MockTestCase.h b/examples/cppunittest/MockTestCase.h new file mode 100644 index 0000000..9cd601c --- /dev/null +++ b/examples/cppunittest/MockTestCase.h @@ -0,0 +1,71 @@ +#ifndef MOCKTESTCASE_H +#define MOCKTESTCASE_H + +#include <cppunit/TestCase.h> + + +/*! \class MockTestCase + * \brief This class represents a mock test case. + */ +class MockTestCase : public CppUnit::TestCase +{ +public: + typedef CppUnit::TestCase SuperClass; // work around VC++ call to super class method. + + /*! Constructs a MockTestCase object. + */ + MockTestCase( std::string name ); + + /// Destructor. + virtual ~MockTestCase(); + + void setExpectedSetUpCall( int callCount = 1 ); + void setExpectedTearDownCall( int callCount = 1 ); + void setExpectedRunTestCall( int callCount = 1 ); + void setExpectedCountTestCasesCall( int callCount = 1 ); + + void makeSetUpThrow(); + void makeTearDownThrow(); + void makeRunTestThrow(); + + void verify(); + +protected: + int countTestCases() const; + void setUp(); + void tearDown(); + void runTest(); + +private: + /// Prevents the use of the copy constructor. + MockTestCase( const MockTestCase © ); + + /// Prevents the use of the copy operator. + void operator =( const MockTestCase © ); + +private: + bool m_hasSetUpExpectation; + int m_expectedSetUpCall; + int m_actualSetUpCall; + + bool m_hasTearDownExpectation; + int m_expectedTearDownCall; + int m_actualTearDownCall; + + bool m_expectRunTestCall; + int m_expectedRunTestCallCount; + int m_actualRunTestCallCount; + bool m_expectCountTestCasesCall; + int m_expectedCountTestCasesCallCount; + mutable int m_actualCountTestCasesCallCount; + + bool m_setUpThrow; + bool m_tearDownThrow; + bool m_runTestThrow; +}; + + + + + +#endif // MOCKTESTCASE_H diff --git a/examples/cppunittest/MockTestListener.cpp b/examples/cppunittest/MockTestListener.cpp index 6c8a056..410a0ee 100644 --- a/examples/cppunittest/MockTestListener.cpp +++ b/examples/cppunittest/MockTestListener.cpp @@ -1,49 +1,192 @@ +#include <cppunit/TestAssert.h> +#include <cppunit/TestFailure.h> #include "MockTestListener.h" -MockTestListener::MockTestListener() +MockTestListener::MockTestListener( std::string name ) + : m_name( name ) + , m_hasExpectationForStartTest( false ) + , m_hasParametersExpectationForStartTest( false ) + , m_expectedStartTestCallCount( 0 ) + , m_startTestCall( 0 ) + , m_hasExpectationForEndTest( false ) + , m_hasParametersExpectationForEndTest( false ) + , m_expectedEndTestCallCount( 0 ) + , m_endTestCall( 0 ) + , m_hasExpectationForAddFailure( false ) + , m_hasExpectationForSomeFailure( false ) + , m_hasParametersExpectationForAddFailure( false ) + , m_expectedAddFailureCallCount( 0 ) + , m_addFailureCall( 0 ) + , m_expectedFailedTest( NULL ) + , m_expectedException( NULL ) + , m_expectedIsError( false ) { - reset(); } void -MockTestListener::addError( CppUnit::Test *test, CppUnit::Exception *e ) +MockTestListener::setExpectFailure( CppUnit::Test *failedTest, + CppUnit::Exception *thrownException, + bool isError ) { - m_called = true; + m_hasExpectationForAddFailure = true; + m_hasParametersExpectationForAddFailure = true; + m_expectedAddFailureCallCount = 1; + m_expectedFailedTest = failedTest; + m_expectedException = thrownException; + m_expectedIsError = isError; } void -MockTestListener::addFailure( CppUnit::Test *test, CppUnit::Exception *e ) +MockTestListener::setExpectNoFailure() { - m_called = true; + m_hasExpectationForAddFailure = true; + m_expectedAddFailureCallCount = 0; } void -MockTestListener::startTest( CppUnit::Test *test ) +MockTestListener::setExpectFailure() { - m_called = true; + m_hasExpectationForSomeFailure = true; } void -MockTestListener::endTest( CppUnit::Test *test ) +MockTestListener::setExpectedAddFailureCall( int callCount ) +{ + m_hasExpectationForAddFailure = true; + m_expectedAddFailureCallCount = callCount; +} + + +void +MockTestListener::setExpectStartTest( CppUnit::Test *test ) +{ + m_hasExpectationForStartTest = true; + m_hasParametersExpectationForStartTest = true; + m_expectedStartTestCallCount = 1; + m_expectedStartTest = test; +} + + +void +MockTestListener::setExpectedStartTestCall( int callCount ) +{ + m_hasExpectationForStartTest = true; + m_expectedStartTestCallCount = callCount; +} + + +void +MockTestListener::setExpectEndTest( CppUnit::Test *test ) +{ + m_hasExpectationForEndTest = true; + m_hasParametersExpectationForEndTest = true; + m_expectedEndTestCallCount = 1; + m_expectedEndTest = test; +} + + +void +MockTestListener::setExpectedEndTestCall( int callCount ) { - m_called = true; + m_hasExpectationForEndTest = true; + m_expectedEndTestCallCount = callCount; } -bool -MockTestListener::wasCalled() const +void +MockTestListener::addFailure( const CppUnit::TestFailure &failure ) { - return m_called; + if ( m_hasExpectationForAddFailure || m_hasExpectationForSomeFailure ) + ++m_addFailureCall; + + if ( m_hasExpectationForAddFailure ) + { + CPPUNIT_ASSERT_MESSAGE( m_name + ": unexpected call", + m_addFailureCall <= m_expectedAddFailureCallCount ); + } + + if ( m_hasParametersExpectationForAddFailure ) + { + CPPUNIT_ASSERT_MESSAGE( m_name + ": bad test", + m_expectedFailedTest == failure.failedTest() ); + CPPUNIT_ASSERT_MESSAGE( m_name + ": bad thrownException", + m_expectedException == failure.thrownException() ); + CPPUNIT_ASSERT_MESSAGE( m_name + ": bad isError", + m_expectedIsError == failure.isError() ); + } } void -MockTestListener::reset() +MockTestListener::startTest( CppUnit::Test *test ) { - m_called = false; + if ( m_hasExpectationForStartTest ) + { + ++m_startTestCall; + CPPUNIT_ASSERT_MESSAGE( m_name + ": unexpected call", + m_startTestCall <= m_expectedStartTestCallCount ); + + } + + if ( m_hasParametersExpectationForStartTest ) + { + CPPUNIT_ASSERT_MESSAGE( m_name + ": bad test", + m_expectedStartTest == test ); + } +} + + +void +MockTestListener::endTest( CppUnit::Test *test ) +{ + if ( m_hasExpectationForEndTest ) + { + ++m_endTestCall; + CPPUNIT_ASSERT_MESSAGE( m_name + ": unexpected call", + m_endTestCall <= m_expectedEndTestCallCount ); + } + + if ( m_hasParametersExpectationForEndTest ) + { + CPPUNIT_ASSERT_MESSAGE( m_name + ": bad test", + m_expectedEndTest == test ); + } +} + + +void +MockTestListener::verify() +{ + if ( m_hasExpectationForStartTest ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedStartTestCallCount, + m_startTestCall, + m_name + ": missing startTest calls" ); + } + + if ( m_hasExpectationForEndTest ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedEndTestCallCount, + m_endTestCall, + m_name + ": missing endTest calls" ); + } + + if ( m_hasExpectationForAddFailure ) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( m_expectedAddFailureCallCount, + m_addFailureCall, + m_name + ": missing addFailure calls" ); + } + + if ( m_hasExpectationForSomeFailure ) + { + CPPUNIT_ASSERT_MESSAGE( m_name + ": there was no call to " + "MockTestListener::addFailure()", + m_addFailureCall > 0 ); + } } diff --git a/examples/cppunittest/MockTestListener.h b/examples/cppunittest/MockTestListener.h index 4f5def1..691ded8 100644 --- a/examples/cppunittest/MockTestListener.h +++ b/examples/cppunittest/MockTestListener.h @@ -2,24 +2,55 @@ #define MOCKTESTLISTENER_H #include <cppunit/TestListener.h> +#include <string> class MockTestListener : public CppUnit::TestListener { public: - MockTestListener(); + MockTestListener( std::string name ); virtual ~MockTestListener() {} - virtual void addError( CppUnit::Test *test, CppUnit::Exception *e ); - virtual void addFailure( CppUnit::Test *test, CppUnit::Exception *e ); - virtual void startTest( CppUnit::Test *test ); - virtual void endTest( CppUnit::Test *test ); + void setExpectFailure( CppUnit::Test *failedTest, + CppUnit::Exception *thrownException, + bool isError ); + void setExpectNoFailure(); + void setExpectFailure(); + void setExpectedAddFailureCall( int callCount ); + void setExpectStartTest( CppUnit::Test *test ); + void setExpectedStartTestCall( int callCount ); + void setExpectEndTest( CppUnit::Test *test ); + void setExpectedEndTestCall( int callCount ); - bool wasCalled() const; - void reset(); + void addFailure( const CppUnit::TestFailure &failure ); + void startTest( CppUnit::Test *test ); + void endTest( CppUnit::Test *test ); + + void verify(); private: - bool m_called; + std::string m_name; + + bool m_hasExpectationForStartTest; + bool m_hasParametersExpectationForStartTest; + int m_expectedStartTestCallCount; + int m_startTestCall; + CppUnit::Test *m_expectedStartTest; + + bool m_hasExpectationForEndTest; + bool m_hasParametersExpectationForEndTest; + int m_expectedEndTestCallCount; + CppUnit::Test *m_expectedEndTest; + int m_endTestCall; + + bool m_hasExpectationForAddFailure; + bool m_hasExpectationForSomeFailure; + bool m_hasParametersExpectationForAddFailure; + int m_expectedAddFailureCallCount; + int m_addFailureCall; + CppUnit::Test *m_expectedFailedTest; + CppUnit::Exception *m_expectedException; + bool m_expectedIsError; }; diff --git a/examples/cppunittest/OrthodoxTest.cpp b/examples/cppunittest/OrthodoxTest.cpp index 390163f..b20fbe3 100644 --- a/examples/cppunittest/OrthodoxTest.cpp +++ b/examples/cppunittest/OrthodoxTest.cpp @@ -19,7 +19,9 @@ OrthodoxTest::~OrthodoxTest() void OrthodoxTest::setUp() { + m_testListener = new MockTestListener( "mock-listener" ); m_result = new CppUnit::TestResult(); + m_result->addListener( m_testListener ); } @@ -27,6 +29,7 @@ void OrthodoxTest::tearDown() { delete m_result; + delete m_testListener; } @@ -34,8 +37,9 @@ void OrthodoxTest::testValue() { CppUnit::Orthodox<Value> test; + m_testListener->setExpectNoFailure(); test.run( m_result ); - checkSuccess(); + m_testListener->verify(); } @@ -43,8 +47,9 @@ void OrthodoxTest::testValueBadConstructor() { CppUnit::Orthodox<ValueBadConstructor> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } @@ -52,8 +57,9 @@ void OrthodoxTest::testValueBadInvert() { CppUnit::Orthodox<ValueBadInvert> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } @@ -61,8 +67,9 @@ void OrthodoxTest::testValueBadEqual() { CppUnit::Orthodox<ValueBadEqual> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } @@ -70,8 +77,9 @@ void OrthodoxTest::testValueBadNotEqual() { CppUnit::Orthodox<ValueBadNotEqual> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } @@ -79,8 +87,9 @@ void OrthodoxTest::testValueBadCall() { CppUnit::Orthodox<ValueBadCall> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } @@ -88,24 +97,7 @@ void OrthodoxTest::testValueBadAssignment() { CppUnit::Orthodox<ValueBadAssignment> test; + m_testListener->setExpectFailure(); test.run( m_result ); - checkFailure(); + m_testListener->verify(); } - - -void -OrthodoxTest::checkSuccess() -{ - CPPUNIT_ASSERT_EQUAL( 0, m_result->testErrors() ); - CPPUNIT_ASSERT_EQUAL( 0, m_result->testFailures() ); - CPPUNIT_ASSERT( m_result->runTests() > 0 ); -} - - -void -OrthodoxTest::checkFailure() -{ - CPPUNIT_ASSERT( m_result->testErrors() > 0 || - m_result->testFailures() > 0 ); -} - diff --git a/examples/cppunittest/OrthodoxTest.h b/examples/cppunittest/OrthodoxTest.h index 8c062b9..679aae7 100644 --- a/examples/cppunittest/OrthodoxTest.h +++ b/examples/cppunittest/OrthodoxTest.h @@ -2,6 +2,7 @@ #define ORTHODOXTEST_H #include <cppunit/extensions/HelperMacros.h> +#include "MockTestListener.h" class OrthodoxTest : public CppUnit::TestCase @@ -167,11 +168,9 @@ private: OrthodoxTest( const OrthodoxTest © ); void operator =( const OrthodoxTest © ); - void checkSuccess(); - void checkFailure(); - private: CppUnit::TestResult *m_result; + MockTestListener *m_testListener; }; diff --git a/examples/cppunittest/SynchronizedTestResult.h b/examples/cppunittest/SynchronizedTestResult.h index 78ce2bb..fca3d26 100644 --- a/examples/cppunittest/SynchronizedTestResult.h +++ b/examples/cppunittest/SynchronizedTestResult.h @@ -1,10 +1,10 @@ #ifndef SYNCHRONIZEDTESTRESULT_H #define SYNCHRONIZEDTESTRESULT_H -#include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> -class SynchronizedTestResult : public CppUnit::TestResult +class SynchronizedTestResult : public CppUnit::TestResultCollector { public: @@ -16,7 +16,7 @@ public: virtual void unlocked() {} }; - class ObservedSynchronizationObject : public CppUnit::TestResult::SynchronizationObject + class ObservedSynchronizationObject : public CppUnit::SynchronizedObject::SynchronizationObject { public: ObservedSynchronizationObject( SynchronizationObjectListener *listener ) : diff --git a/examples/cppunittest/TestCallerTest.cpp b/examples/cppunittest/TestCallerTest.cpp index 5584696..e5e5db9 100644 --- a/examples/cppunittest/TestCallerTest.cpp +++ b/examples/cppunittest/TestCallerTest.cpp @@ -41,22 +41,6 @@ TestCallerTest::~TestCallerTest() } -CppUnit::TestSuite * -TestCallerTest::suite() -{ - CppUnit::TestSuiteBuilder<TestCallerTest> suite("TestCallerTest"); - - suite.addTestCaller( "testBasicConstructor", &TestCallerTest::testBasicConstructor ); - suite.addTestCaller( "testReferenceConstructor", &TestCallerTest::testReferenceConstructor ); - suite.addTestCaller( "testPointerConstructor", &TestCallerTest::testPointerConstructor ); - suite.addTestCaller( "testExpectFailureException", &TestCallerTest::testExpectFailureException ); - suite.addTestCaller( "testExpectException", &TestCallerTest::testExpectException ); - suite.addTestCaller( "testExpectedExceptionNotCaught", &TestCallerTest::testExpectedExceptionNotCaught ); - - return suite.takeSuite(); -} - - void TestCallerTest::setUp() { @@ -66,7 +50,9 @@ TestCallerTest::setUp() m_tearDownCount = 0; m_testCount = 0; TrackedTestCase::setTracker( this ); + m_testListener = new MockTestListener( "listener1" ); m_result = new CppUnit::TestResult(); + m_result->addListener( m_testListener ); } @@ -75,6 +61,7 @@ TestCallerTest::tearDown() { TrackedTestCase::removeTracker(); delete m_result; + delete m_testListener; } @@ -174,8 +161,9 @@ TestCallerTest::testExpectFailureException() CppUnit::TestCaller<ExceptionThrower,FailureException> caller( m_testName, &ExceptionThrower::testThrowFailureException ); + m_testListener->setExpectNoFailure(); caller.run( m_result ); - CPPUNIT_ASSERT( m_result->wasSuccessful() ); + m_testListener->verify(); } @@ -185,8 +173,9 @@ TestCallerTest::testExpectException() CppUnit::TestCaller<ExceptionThrower,CppUnit::Exception> caller( m_testName, &ExceptionThrower::testThrowException ); + m_testListener->setExpectNoFailure(); caller.run( m_result ); - CPPUNIT_ASSERT( m_result->wasSuccessful() ); + m_testListener->verify(); } @@ -196,14 +185,9 @@ TestCallerTest::testExpectedExceptionNotCaught() CppUnit::TestCaller<ExceptionThrower,FailureException> caller( m_testName, &ExceptionThrower::testThrowNothing ); + m_testListener->setExpectedAddFailureCall( 1 ); caller.run( m_result ); - CPPUNIT_ASSERT( !m_result->wasSuccessful() ); - CPPUNIT_ASSERT_EQUAL( 1, int(m_result->failures().size()) ); -// Can differentiate throw 'new Exception' from throw 'Exception' -// only by text message which is unsafe. -// Possible solution: subclass Exception: -// CppUnit::Exception *e = m_result->failues()[0]->thrownException(); -// CPPUNIT_ASSERT( e->isInstanceOf( FailureException::type() ) ); + m_testListener->verify(); } diff --git a/examples/cppunittest/TestCallerTest.h b/examples/cppunittest/TestCallerTest.h index bb6e7b7..e51369a 100644 --- a/examples/cppunittest/TestCallerTest.h +++ b/examples/cppunittest/TestCallerTest.h @@ -1,23 +1,30 @@ #ifndef TESTCALLERTEST_H #define TESTCALLERTEST_H +#include <cppunit/extensions/HelperMacros.h> #include <cppunit/TestCase.h> #include <cppunit/TestResult.h> #include <cppunit/TestSuite.h> +#include "MockTestListener.h" #include "TrackedTestCase.h" - class TestCallerTest : public CppUnit::TestCase, Tracker { + CPPUNIT_TEST_SUITE( TestCallerTest ); + CPPUNIT_TEST( testBasicConstructor ); + CPPUNIT_TEST( testReferenceConstructor ); + CPPUNIT_TEST( testPointerConstructor ); + CPPUNIT_TEST( testExpectFailureException ); + CPPUNIT_TEST( testExpectException ); + CPPUNIT_TEST( testExpectedExceptionNotCaught ); + CPPUNIT_TEST_SUITE_END(); public: TestCallerTest(); virtual ~TestCallerTest(); - static CppUnit::TestSuite *suite(); - - virtual void setUp(); - virtual void tearDown(); + void setUp(); + void tearDown(); void testBasicConstructor(); void testReferenceConstructor(); @@ -56,6 +63,7 @@ private: int m_tearDownCount; int m_testCount; const std::string m_testName; + MockTestListener *m_testListener; CppUnit::TestResult *m_result; }; diff --git a/examples/cppunittest/TestCaseTest.cpp b/examples/cppunittest/TestCaseTest.cpp index 81e0c4a..5479c0e 100644 --- a/examples/cppunittest/TestCaseTest.cpp +++ b/examples/cppunittest/TestCaseTest.cpp @@ -1,6 +1,7 @@ #include "CoreSuite.h" +#include "FailureException.h" +#include "MockTestCase.h" #include "TestCaseTest.h" -#include "FailingTestCase.h" #include <cppunit/TestResult.h> /* @@ -25,7 +26,9 @@ TestCaseTest::~TestCaseTest() void TestCaseTest::setUp() { + m_testListener = new MockTestListener( "mock-testlistener" ); m_result = new CppUnit::TestResult(); + m_result->addListener( m_testListener ); } @@ -33,6 +36,7 @@ void TestCaseTest::tearDown() { delete m_result; + delete m_testListener; } @@ -78,13 +82,24 @@ TestCaseTest::checkFailure( bool failSetUp, { try { - FailingTestCase test( failSetUp, failRunTest, failTearDown ); - test.run( m_result ); - test.verify( !failSetUp, !failSetUp ); + MockTestCase testCase( "mock-test" ); + if ( failSetUp ) + testCase.makeSetUpThrow(); + if ( failRunTest ) + testCase.makeRunTestThrow(); + if ( failTearDown ) + testCase.makeTearDownThrow(); + testCase.setExpectedSetUpCall( 1 ); + testCase.setExpectedRunTestCall( failSetUp ? 0 : 1 ); + testCase.setExpectedTearDownCall( failSetUp ? 0 : 1 ); + + testCase.run( m_result ); + + testCase.verify(); } catch ( FailureException & ) { - CPPUNIT_ASSERT_MESSAGE( "exception should have been catched", false ); + CPPUNIT_ASSERT_MESSAGE( "exception should have been caught", false ); } } @@ -117,34 +132,27 @@ TestCaseTest::testConstructorWithName() void TestCaseTest::testDefaultRun() { - CppUnit::TestCase test; - std::auto_ptr<CppUnit::TestResult> result( test.run() ); + MockTestCase test( "mocktest" ); + test.setExpectedSetUpCall(); + test.setExpectedRunTestCall(); + test.setExpectedTearDownCall(); - checkResult( 0, 0, 1, result.get() ); + std::auto_ptr<CppUnit::TestResult> result( test.run() ); + test.verify(); } void TestCaseTest::testTwoRun() { - FailingTestCase test1( false, true, false ); + MockTestCase test1( "mocktest1" ); + test1.makeRunTestThrow(); + m_testListener->setExpectedStartTestCall( 2 ); + m_testListener->setExpectedAddFailureCall( 2 ); + m_testListener->setExpectedEndTestCall( 2 ); + test1.run( m_result ); test1.run( m_result ); - - FailingTestCase test2( false, false, false ); - test2.run( m_result ); - checkResult( 2, 0, 1, m_result ); -} - - -void -TestCaseTest::checkResult( int failures, - int errors, - int testsRun, - CppUnit::TestResult *result ) -{ - CPPUNIT_ASSERT_EQUAL( testsRun, result->runTests() ); - CPPUNIT_ASSERT_EQUAL( errors, result->testErrors() ); - CPPUNIT_ASSERT_EQUAL( failures, result->testFailures() ); + m_testListener->verify(); } diff --git a/examples/cppunittest/TestCaseTest.h b/examples/cppunittest/TestCaseTest.h index 16a6e37..050f71f 100644 --- a/examples/cppunittest/TestCaseTest.h +++ b/examples/cppunittest/TestCaseTest.h @@ -8,6 +8,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/TestResult.h> +#include "MockTestListener.h" class TestCaseTest : public CppUnit::TestCase @@ -19,6 +20,7 @@ class TestCaseTest : public CppUnit::TestCase CPPUNIT_TEST( testFailAll ); CPPUNIT_TEST( testNoFailure ); CPPUNIT_TEST( testDefaultRun ); + CPPUNIT_TEST( testTwoRun ); CPPUNIT_TEST( testCountTestCases ); CPPUNIT_TEST( testDefaultConstructor ); CPPUNIT_TEST( testConstructorWithName ); @@ -53,13 +55,15 @@ private: void checkFailure( bool failSetUp, bool failRunTest, bool failTearDown ); - +/* void checkResult( int failures, int errors, int testsRun, CppUnit::TestResult *result ); +*/ private: CppUnit::TestResult *m_result; + MockTestListener *m_testListener; }; diff --git a/examples/cppunittest/TestDecoratorTest.cpp b/examples/cppunittest/TestDecoratorTest.cpp index 0bf17fd..8ff257d 100644 --- a/examples/cppunittest/TestDecoratorTest.cpp +++ b/examples/cppunittest/TestDecoratorTest.cpp @@ -1,5 +1,4 @@ #include "ExtensionSuite.h" -#include "FailingTestCase.h" #include "TestDecoratorTest.h" #include <cppunit/TestResult.h> @@ -21,7 +20,7 @@ TestDecoratorTest::~TestDecoratorTest() void TestDecoratorTest::setUp() { - m_test = new FailingTestCase(); + m_test = new MockTestCase( "mocktest" ); m_decorator = new CppUnit::TestDecorator( m_test ); } @@ -37,14 +36,20 @@ TestDecoratorTest::tearDown() void TestDecoratorTest::testCountTestCases() { + m_test->setExpectedCountTestCasesCall( 1 ); CPPUNIT_ASSERT_EQUAL( 1, m_decorator->countTestCases() ); + m_test->verify(); } void TestDecoratorTest::testRun() { + m_test->setExpectedSetUpCall( 1 ); + m_test->setExpectedRunTestCall( 1 ); + m_test->setExpectedTearDownCall( 1 ); CppUnit::TestResult result; + m_decorator->run( &result ); m_test->verify(); } diff --git a/examples/cppunittest/TestDecoratorTest.h b/examples/cppunittest/TestDecoratorTest.h index b795afd..3789d63 100644 --- a/examples/cppunittest/TestDecoratorTest.h +++ b/examples/cppunittest/TestDecoratorTest.h @@ -3,7 +3,7 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestDecorator.h> -class FailingTestCase; +#include "MockTestCase.h" class TestDecoratorTest : public CppUnit::TestCase @@ -30,8 +30,8 @@ private: void operator =( const TestDecoratorTest © ); private: - CppUnit::Test *m_decorator; - FailingTestCase *m_test; + MockTestCase *m_test; + CppUnit::TestDecorator *m_decorator; }; diff --git a/examples/cppunittest/TestListenerTest.cpp b/examples/cppunittest/TestListenerTest.cpp deleted file mode 100644 index b7d0e68..0000000 --- a/examples/cppunittest/TestListenerTest.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include "CoreSuite.h" -#include "MockTestListener.h" -#include "TestListenerTest.h" -#include <cppunit/extensions/TestSuiteBuilder.h> -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestResult.h> - -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TestListenerTest, - CppUnitTest::coreSuiteName() ); - - -TestListenerTest::TestListenerTest() : - CppUnit::TestCase() -{ -} - - -TestListenerTest::~TestListenerTest() -{ -} - - -CppUnit::TestSuite * -TestListenerTest::suite() -{ - CppUnit::TestSuiteBuilder<TestListenerTest> suite("TestListenerTest"); - - suite.addTestCaller( "testNoListener", &TestListenerTest::testNoListener ); - suite.addTestCaller( "testAddErrorListener", - &TestListenerTest::testAddErrorListener ); - suite.addTestCaller( "testAddFailureListener", - &TestListenerTest::testAddFailureListener ); - suite.addTestCaller( "testStartTestListener", - &TestListenerTest::testStartTestListener ); - suite.addTestCaller( "testEndTestListener", - &TestListenerTest::testEndTestListener ); - suite.addTestCaller( "testRemoveFrontListener", - &TestListenerTest::testRemoveFrontListener ); - suite.addTestCaller( "testRemoveLastListener", - &TestListenerTest::testRemoveLastListener ); - - return suite.takeSuite(); -} - - -void -TestListenerTest::setUp() -{ - m_listenerTest = NULL; - m_listenerError = NULL; - m_dummyTest = new CppUnit::TestCase( "DummyTest" ); - m_dummyError = NULL; - m_listenerCallbackType = undefined; - m_result = new CppUnit::TestResult(); - m_result->addListener( this ); -} - - -void -TestListenerTest::tearDown() -{ - m_result->removeListener( this ); - delete m_result; - delete m_dummyTest; -} - - -void -TestListenerTest::addFailure( CppUnit::TestFailure *failure ) -{ - m_listenerTest = failure->failedTest(); - m_listenerError = failure->thrownException(); - m_listenerCallbackType = failure->isError() ? onAddError : - onAddFailure; -} - - -void -TestListenerTest::startTest( CppUnit::Test *test ) -{ - m_listenerTest = test; - m_listenerCallbackType = onStartTest; -} - - -void -TestListenerTest::endTest( CppUnit::Test *test ) -{ - m_listenerTest = test; - m_listenerCallbackType = onEndTest; -} - - -void -TestListenerTest::testAddErrorListener() -{ - m_result->addError( m_dummyTest, makeDummyError() ); - CPPUNIT_ASSERT( m_listenerCallbackType == onAddError ); - CPPUNIT_ASSERT( m_listenerTest == m_dummyTest ); - CPPUNIT_ASSERT( m_listenerError == m_dummyError ); -} - - -void -TestListenerTest::testAddFailureListener() -{ - m_result->addFailure( m_dummyTest, makeDummyError() ); - CPPUNIT_ASSERT( m_listenerCallbackType == onAddFailure ); - CPPUNIT_ASSERT( m_listenerTest == m_dummyTest ); - CPPUNIT_ASSERT( m_listenerError == m_dummyError ); -} - - -void -TestListenerTest::testStartTestListener() -{ - m_result->startTest( m_dummyTest ); - CPPUNIT_ASSERT( m_listenerCallbackType == onStartTest ); - CPPUNIT_ASSERT( m_listenerTest == m_dummyTest ); -} - - -void -TestListenerTest::testEndTestListener() -{ - m_result->endTest( m_dummyTest ); - CPPUNIT_ASSERT( m_listenerCallbackType == onEndTest ); - CPPUNIT_ASSERT( m_listenerTest == m_dummyTest ); -} - - -CppUnit::Exception * -TestListenerTest::makeDummyError() -{ - m_dummyError = new CppUnit::Exception( "dummy exception" ); - return m_dummyError; -} - - -void -TestListenerTest::testNoListener() -{ - CppUnit::TestResult result; - result.addError( m_dummyTest, makeDummyError() ); - result.addFailure( m_dummyTest, makeDummyError() ); - result.startTest( m_dummyTest ); - result.endTest( m_dummyTest ); -} - - -void -TestListenerTest::testTwoListener() -{ - MockTestListener listener; - m_result->addListener( &listener ); - m_result->startTest( m_dummyTest ); - CPPUNIT_ASSERT( m_listenerCallbackType == onStartTest ); - CPPUNIT_ASSERT( listener.wasCalled() ); -} - - -void -TestListenerTest::testRemoveFrontListener() -{ - MockTestListener listener; - m_result->addListener( &listener ); - m_result->removeListener( &listener ); - m_result->startTest( m_dummyTest ); - CPPUNIT_ASSERT( m_listenerCallbackType == onStartTest ); - CPPUNIT_ASSERT( !listener.wasCalled() ); -} - - -void -TestListenerTest::testRemoveLastListener() -{ - MockTestListener listener; - m_result->addListener( &listener ); - - m_result->removeListener( this ); - m_result->startTest( m_dummyTest ); - CPPUNIT_ASSERT( m_listenerCallbackType == undefined ); - CPPUNIT_ASSERT( listener.wasCalled() ); -} diff --git a/examples/cppunittest/TestListenerTest.h b/examples/cppunittest/TestListenerTest.h deleted file mode 100644 index 6b0ac32..0000000 --- a/examples/cppunittest/TestListenerTest.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef TESTLISTENERTEST_H -#define TESTLISTENERTEST_H - -#include <cppunit/TestCase.h> -#include <cppunit/TestSuite.h> -#include <cppunit/TestListener.h> - - -class TestListenerTest : public CppUnit::TestCase, - public CppUnit::TestListener -{ -public: - TestListenerTest(); - - virtual ~TestListenerTest(); - - static CppUnit::TestSuite *suite(); - - virtual void setUp(); - virtual void tearDown(); - - void testAddErrorListener(); - void testAddFailureListener(); - void testStartTestListener(); - void testEndTestListener(); - - void testNoListener(); - void testTwoListener(); - - void testRemoveLastListener(); - void testRemoveFrontListener(); - -private: - enum ListenerCallbackType { - undefined, - onAddError, - onAddFailure, - onStartTest, - onEndTest - }; - - void addFailure( CppUnit::TestFailure *failure ); - void startTest( CppUnit::Test *test ); - void endTest( CppUnit::Test *test ); - - CppUnit::Exception *makeDummyError(); - - TestListenerTest( const TestListenerTest © ); - void operator =( const TestListenerTest © ); - -private: - CppUnit::Test *m_listenerTest; - CppUnit::Exception *m_listenerError; - CppUnit::Test *m_dummyTest; - CppUnit::Exception *m_dummyError; - CppUnit::TestResult *m_result; - ListenerCallbackType m_listenerCallbackType; -}; - - -#endif // TESTLISTENERTEST_H diff --git a/examples/cppunittest/TestResultCollectorTest.cpp b/examples/cppunittest/TestResultCollectorTest.cpp new file mode 100644 index 0000000..bac6485 --- /dev/null +++ b/examples/cppunittest/TestResultCollectorTest.cpp @@ -0,0 +1,297 @@ +#include "CoreSuite.h" +#include "TestResultCollectorTest.h" + + + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TestResultCollectorTest, + CppUnitTest::coreSuiteName() ); + + +TestResultCollectorTest::TestResultCollectorTest() +{ +} + + +TestResultCollectorTest::~TestResultCollectorTest() +{ +} + + +void +TestResultCollectorTest::setUp() +{ + m_lockCount = 0; + m_unlockCount = 0; + m_result = new CppUnit::TestResultCollector(); + m_synchronizedResult = new SynchronizedTestResult( this ); + m_test = new CppUnit::TestCase(); + m_test2 = new CppUnit::TestCase(); +} + + +void +TestResultCollectorTest::tearDown() +{ + delete m_test2; + delete m_test; + delete m_synchronizedResult; + delete m_result; +} + + +void +TestResultCollectorTest::testConstructor() +{ + checkResult( 0, 0, 0 ); +} + + +void +TestResultCollectorTest::testAddTwoErrors() +{ + std::string errorMessage1( "First Error" ); + std::string errorMessage2( "Second Error" ); + { + CppUnit::TestFailure failure1( m_test, + new CppUnit::Exception( errorMessage1 ), + true ); + m_result->addFailure( failure1 ); + + CppUnit::TestFailure failure2( m_test2, + new CppUnit::Exception( errorMessage2 ), + true ); + m_result->addFailure( failure2 ); + } // ensure that the test result duplicate the failures. + + checkResult( 0, 2, 0 ); + checkFailure( m_result->failures()[0], + errorMessage1, + m_test, + true ); + checkFailure( m_result->failures()[1], + errorMessage2, + m_test2, + true ); +} + + +void +TestResultCollectorTest::testAddTwoFailures() +{ + std::string errorMessage1( "First Failure" ); + std::string errorMessage2( "Second Failure" ); + { + CppUnit::TestFailure failure1( m_test, + new CppUnit::Exception( errorMessage1 ), + false ); + m_result->addFailure( failure1 ); + + CppUnit::TestFailure failure2( m_test2, + new CppUnit::Exception( errorMessage2 ), + false ); + m_result->addFailure( failure2 ); + } // ensure that the test result duplicate the failures. + checkResult( 2, 0, 0 ); + checkFailure( m_result->failures()[0], + errorMessage1, + m_test, + false ); + checkFailure( m_result->failures()[1], + errorMessage2, + m_test2, + false ); +} + + +void +TestResultCollectorTest::testStartTest() +{ + m_result->startTest( m_test ); + m_result->startTest( m_test ); + checkResult( 0, 0, 2 ); +} + + +void +TestResultCollectorTest::testWasSuccessfulWithNoTest() +{ + checkWasSuccessful( true ); +} + + +void +TestResultCollectorTest::testWasSuccessfulWithErrors() +{ + addError( "Error1" ); + addError( "Error2" ); + checkWasSuccessful( false ); +} + + +void +TestResultCollectorTest::testWasSuccessfulWithFailures() +{ + addFailure( "Failure1" ); + addFailure( "Failure2" ); + checkWasSuccessful( false ); +} + + +void +TestResultCollectorTest::testWasSuccessfulWithErrorsAndFailures() +{ + addError( "Error1" ); + addFailure( "Failure2" ); + checkWasSuccessful( false ); +} + + +void +TestResultCollectorTest::testWasSuccessfulWithSucessfulTest() +{ + m_result->startTest( m_test ); + m_result->endTest( m_test ); + m_result->startTest( m_test2 ); + m_result->endTest( m_test2 ); + checkWasSuccessful( true ); +} + + +void +TestResultCollectorTest::testSynchronizationAddFailure() +{ + addFailure( "Failure1", m_test, false, m_synchronizedResult ); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationStartTest() +{ + m_synchronizedResult->startTest( m_test ); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationRunTests() +{ + m_synchronizedResult->runTests(); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationTestErrors() +{ + m_synchronizedResult->testErrors(); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationTestFailures() +{ + m_synchronizedResult->testFailures(); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationFailures() +{ + m_synchronizedResult->failures(); + checkSynchronization(); +} + + +void +TestResultCollectorTest::testSynchronizationWasSuccessful() +{ + m_synchronizedResult->wasSuccessful(); + checkSynchronization(); +} + + +void +TestResultCollectorTest::checkResult( int failures, + int errors, + int testsRun ) +{ + CPPUNIT_ASSERT_EQUAL( testsRun, m_result->runTests() ); + CPPUNIT_ASSERT_EQUAL( errors, m_result->testErrors() ); + CPPUNIT_ASSERT_EQUAL( failures, m_result->testFailures() ); + CPPUNIT_ASSERT_EQUAL( errors + failures, + m_result->testFailuresTotal() ); +} + + +void +TestResultCollectorTest::checkFailure( CppUnit::TestFailure *failure, + std::string expectedMessage, + CppUnit::Test *expectedTest, + bool expectedIsError ) +{ + std::string actualMessage( failure->thrownException()->what() ); + CPPUNIT_ASSERT_EQUAL( expectedMessage, actualMessage ); + CPPUNIT_ASSERT_EQUAL( expectedTest, failure->failedTest() ); + CPPUNIT_ASSERT_EQUAL( expectedIsError, failure->isError() ); +} + + +void +TestResultCollectorTest::checkWasSuccessful( bool shouldBeSuccessful ) +{ + CPPUNIT_ASSERT_EQUAL( shouldBeSuccessful, m_result->wasSuccessful() ); +} + + +void +TestResultCollectorTest::locked() +{ + CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); + ++m_lockCount; +} + + +void +TestResultCollectorTest::unlocked() +{ + ++m_unlockCount; + CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); +} + + +void +TestResultCollectorTest::checkSynchronization() +{ + CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); + CPPUNIT_ASSERT( m_lockCount > 0 ); +} + + +void +TestResultCollectorTest::addFailure( std::string message ) +{ + addFailure( message, m_test, false, m_result ); +} + + +void +TestResultCollectorTest::addError( std::string message ) +{ + addFailure( message, m_test, true, m_result ); +} + + +void +TestResultCollectorTest::addFailure( std::string message, + CppUnit::Test *failedTest, + bool isError, + CppUnit::TestResultCollector *result ) +{ + CppUnit::TestFailure failure( failedTest, + new CppUnit::Exception( message ), + isError ); + result->addFailure( failure ); +} diff --git a/examples/cppunittest/TestResultCollectorTest.h b/examples/cppunittest/TestResultCollectorTest.h new file mode 100644 index 0000000..8298a3d --- /dev/null +++ b/examples/cppunittest/TestResultCollectorTest.h @@ -0,0 +1,96 @@ +#ifndef TESTCOLLECTORRESULTTEST_H +#define TESTCOLLECTORRESULTTEST_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestFailure.h> +#include "SynchronizedTestResult.h" + + +class TestResultCollectorTest : public CppUnit::TestCase, + public SynchronizedTestResult::SynchronizationObjectListener +{ + CPPUNIT_TEST_SUITE( TestResultCollectorTest ); + CPPUNIT_TEST( testConstructor ); + CPPUNIT_TEST( testAddTwoErrors ); + CPPUNIT_TEST( testAddTwoFailures ); + CPPUNIT_TEST( testStartTest ); + CPPUNIT_TEST( testWasSuccessfulWithErrors ); + CPPUNIT_TEST( testWasSuccessfulWithFailures ); + CPPUNIT_TEST( testWasSuccessfulWithErrorsAndFailures ); + CPPUNIT_TEST( testWasSuccessfulWithSucessfulTest ); + CPPUNIT_TEST( testSynchronizationAddFailure ); + CPPUNIT_TEST( testSynchronizationStartTest ); + CPPUNIT_TEST( testSynchronizationRunTests ); + CPPUNIT_TEST( testSynchronizationTestErrors ); + CPPUNIT_TEST( testSynchronizationTestFailures ); + CPPUNIT_TEST( testSynchronizationFailures ); + CPPUNIT_TEST( testSynchronizationWasSuccessful ); + CPPUNIT_TEST_SUITE_END(); + +public: + TestResultCollectorTest(); + virtual ~TestResultCollectorTest(); + + virtual void setUp(); + virtual void tearDown(); + + void testConstructor(); + + void testAddTwoErrors(); + void testAddTwoFailures(); + void testStartTest(); + + void testWasSuccessfulWithNoTest(); + void testWasSuccessfulWithErrors(); + void testWasSuccessfulWithFailures(); + void testWasSuccessfulWithErrorsAndFailures(); + void testWasSuccessfulWithSucessfulTest(); + + void testSynchronizationAddFailure(); + void testSynchronizationStartTest(); + void testSynchronizationRunTests(); + void testSynchronizationTestErrors(); + void testSynchronizationTestFailures(); + void testSynchronizationErrors(); + void testSynchronizationFailures(); + void testSynchronizationWasSuccessful(); + + virtual void locked(); + virtual void unlocked(); + +private: + TestResultCollectorTest( const TestResultCollectorTest © ); + void operator =( const TestResultCollectorTest © ); + + void checkResult( int failures, + int errors, + int testsRun ); + + void checkFailure( CppUnit::TestFailure *failure, + std::string expectedMessage, + CppUnit::Test *expectedTest, + bool expectedIsError ); + + void checkWasSuccessful( bool shouldBeSuccessful ); + + void checkSynchronization(); + + void addFailure( std::string message ); + void addError( std::string message ); + void addFailure( std::string message, + CppUnit::Test *failedTest, + bool isError, + CppUnit::TestResultCollector *result ); + +private: + CppUnit::TestResultCollector *m_result; + SynchronizedTestResult *m_synchronizedResult; + CppUnit::Test *m_test; + CppUnit::Test *m_test2; + int m_lockCount; + int m_unlockCount; +}; + + + +#endif // TESTCOLLECTORRESULTTEST_H diff --git a/examples/cppunittest/TestResultTest.cpp b/examples/cppunittest/TestResultTest.cpp index aa9175e..7122a92 100644 --- a/examples/cppunittest/TestResultTest.cpp +++ b/examples/cppunittest/TestResultTest.cpp @@ -1,12 +1,5 @@ #include "CoreSuite.h" #include "TestResultTest.h" -#include <cppunit/TestResult.h> - -/* Note: - - the TestListener part of TestResult is tested in TestListenerTest. - - bug identified: errors() and failures() are synchronized but returns - reference! No unit test for that one (need multihread...). - */ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TestResultTest, @@ -26,21 +19,19 @@ TestResultTest::~TestResultTest() void TestResultTest::setUp() { - m_lockCount = 0; - m_unlockCount = 0; m_result = new CppUnit::TestResult(); - m_synchronizedResult = new SynchronizedTestResult( this ); - m_test = new CppUnit::TestCase(); - m_test2 = new CppUnit::TestCase(); + m_listener1 = new MockTestListener( "listener1" ); + m_listener2 = new MockTestListener( "listener2" ); + m_dummyTest = new CppUnit::TestCase(); } void TestResultTest::tearDown() { - delete m_test2; - delete m_test; - delete m_synchronizedResult; + delete m_dummyTest; + delete m_listener1; + delete m_listener2; delete m_result; } @@ -48,7 +39,6 @@ TestResultTest::tearDown() void TestResultTest::testConstructor() { - checkResult( 0, 0, 0 ); CPPUNIT_ASSERT( !m_result->shouldStop() ); } @@ -62,246 +52,72 @@ TestResultTest::testStop() void -TestResultTest::testAddTwoErrors() -{ - std::string errorMessage1( "First Error" ); - m_result->addError( m_test, new CppUnit::Exception( errorMessage1 ) ); - - std::string errorMessage2( "Second Error" ); - m_result->addError( m_test2, new CppUnit::Exception( errorMessage2 ) ); - checkResult( 0, 2, 0 ); - checkFailure( m_result->failures()[0], - errorMessage1, - m_test, - true ); - checkFailure( m_result->failures()[1], - errorMessage2, - m_test2, - true ); -} - - -void -TestResultTest::testAddTwoFailures() -{ - std::string errorMessage1( "First Failure" ); - m_result->addFailure( m_test, new CppUnit::Exception( errorMessage1 ) ); - - std::string errorMessage2( "Second Failure" ); - m_result->addFailure( m_test2, new CppUnit::Exception( errorMessage2 ) ); - checkResult( 2, 0, 0 ); - checkFailure( m_result->failures()[0], - errorMessage1, - m_test, - false ); - checkFailure( m_result->failures()[1], - errorMessage2, - m_test2, - false ); -} - - -void -TestResultTest::testStartTest() -{ - m_result->startTest( m_test ); - m_result->startTest( m_test ); - checkResult( 0, 0, 2 ); -} - - -void -TestResultTest::testEndTest() +TestResultTest::testAddError() { - // It doesn't actually do anything beyond TestListener stuffs... -} + CppUnit::Exception *dummyException = new CppUnit::Exception( "some_error" ); + m_listener1->setExpectFailure( m_dummyTest, dummyException, true ); + m_result->addListener( m_listener1 ); + m_result->addError( m_dummyTest, dummyException ); -void -TestResultTest::testWasSuccessfulWithNoTest() -{ - checkWasSuccessful( true ); + m_listener1->verify(); } void -TestResultTest::testWasSuccessfulWithErrors() +TestResultTest::testAddFailure() { - m_result->addError( m_test, new CppUnit::Exception( "Error1" ) ); - m_result->addError( m_test, new CppUnit::Exception( "Error2" ) ); - checkWasSuccessful( false ); -} + CppUnit::Exception *dummyException = new CppUnit::Exception( "some_error" ); + m_listener1->setExpectFailure( m_dummyTest, dummyException, false ); + m_result->addListener( m_listener1 ); + m_result->addFailure( m_dummyTest, dummyException ); -void -TestResultTest::testWasSuccessfulWithFailures() -{ - m_result->addFailure( m_test, new CppUnit::Exception( "Failure1" ) ); - m_result->addFailure( m_test, new CppUnit::Exception( "Failure2" ) ); - checkWasSuccessful( false ); + m_listener1->verify(); } void -TestResultTest::testWasSuccessfulWithErrorsAndFailures() -{ - m_result->addError( m_test, new CppUnit::Exception( "Error1" ) ); - m_result->addFailure( m_test, new CppUnit::Exception( "Failure2" ) ); - checkWasSuccessful( false ); -} - - -void -TestResultTest::testWasSuccessfulWithSucessfulTest() -{ - m_result->startTest( m_test ); - m_result->endTest( m_test ); - m_result->startTest( m_test2 ); - m_result->endTest( m_test2 ); - checkWasSuccessful( true ); -} - - -void -TestResultTest::testSynchronizationAddError() -{ - m_synchronizedResult->addError( m_test, new CppUnit::Exception( "Error1" ) ); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationAddFailure() -{ - m_synchronizedResult->addFailure( m_test, new CppUnit::Exception( "Failure1" ) ); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationStartTest() -{ - m_synchronizedResult->startTest( m_test ); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationEndTest() -{ - m_synchronizedResult->endTest( m_test ); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationRunTests() -{ - m_synchronizedResult->runTests(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationTestErrors() -{ - m_synchronizedResult->testErrors(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationTestFailures() -{ - m_synchronizedResult->testFailures(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationFailures() -{ - m_synchronizedResult->failures(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationWasSuccessful() -{ - m_synchronizedResult->wasSuccessful(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationShouldStop() -{ - m_synchronizedResult->shouldStop(); - checkSynchronization(); -} - - -void -TestResultTest::testSynchronizationStop() -{ - m_synchronizedResult->stop(); - checkSynchronization(); -} - - -void -TestResultTest::checkResult( int failures, - int errors, - int testsRun ) +TestResultTest::testStartTest() { - CPPUNIT_ASSERT_EQUAL( testsRun, m_result->runTests() ); - CPPUNIT_ASSERT_EQUAL( errors, m_result->testErrors() ); - CPPUNIT_ASSERT_EQUAL( failures, m_result->testFailures() ); - CPPUNIT_ASSERT_EQUAL( errors + failures, - m_result->testFailuresTotal() ); -} - + m_listener1->setExpectStartTest( m_dummyTest ); + m_result->addListener( m_listener1 ); + + m_result->startTest( m_dummyTest ); -void -TestResultTest::checkFailure( CppUnit::TestFailure *failure, - std::string expectedMessage, - CppUnit::Test *expectedTest, - bool expectedIsError ) -{ - std::string actualMessage( failure->thrownException()->what() ); - CPPUNIT_ASSERT_EQUAL( expectedMessage, actualMessage ); - CPPUNIT_ASSERT_EQUAL( expectedTest, failure->failedTest() ); - CPPUNIT_ASSERT_EQUAL( expectedIsError, failure->isError() ); + m_listener1->verify(); } void -TestResultTest::checkWasSuccessful( bool shouldBeSuccessful ) +TestResultTest::testEndTest() { - CPPUNIT_ASSERT_EQUAL( shouldBeSuccessful, m_result->wasSuccessful() ); -} + m_listener1->setExpectEndTest( m_dummyTest ); + m_result->addListener( m_listener1 ); + + m_result->endTest( m_dummyTest ); - -void -TestResultTest::locked() -{ - CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); - ++m_lockCount; + m_listener1->verify(); } void -TestResultTest::unlocked() +TestResultTest::testTwoListener() { - ++m_unlockCount; - CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); -} + m_listener1->setExpectStartTest( m_dummyTest ); + m_listener2->setExpectStartTest( m_dummyTest ); + CppUnit::Exception *dummyException1 = new CppUnit::Exception( "some_error" ); + m_listener1->setExpectFailure( m_dummyTest, dummyException1, true ); + m_listener2->setExpectFailure( m_dummyTest, dummyException1, true ); + m_listener1->setExpectEndTest( m_dummyTest ); + m_listener2->setExpectEndTest( m_dummyTest ); + m_result->addListener( m_listener1 ); + m_result->addListener( m_listener2 ); + m_result->startTest( m_dummyTest ); + m_result->addError( m_dummyTest, dummyException1 ); + m_result->endTest( m_dummyTest ); -void -TestResultTest::checkSynchronization() -{ - CPPUNIT_ASSERT_EQUAL( m_lockCount, m_unlockCount ); - CPPUNIT_ASSERT( m_lockCount > 0 ); + m_listener1->verify(); + m_listener2->verify(); } diff --git a/examples/cppunittest/TestResultTest.h b/examples/cppunittest/TestResultTest.h index dea50c4..e273dcf 100644 --- a/examples/cppunittest/TestResultTest.h +++ b/examples/cppunittest/TestResultTest.h @@ -2,35 +2,20 @@ #define TESTRESULTTEST_H #include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestFailure.h> -#include "SynchronizedTestResult.h" +#include <cppunit/TestResult.h> +#include "MockTestListener.h" -class TestResultTest : public CppUnit::TestCase, - public SynchronizedTestResult::SynchronizationObjectListener +class TestResultTest : public CppUnit::TestCase { CPPUNIT_TEST_SUITE( TestResultTest ); CPPUNIT_TEST( testConstructor ); CPPUNIT_TEST( testStop ); - CPPUNIT_TEST( testAddTwoErrors ); - CPPUNIT_TEST( testAddTwoFailures ); + CPPUNIT_TEST( testAddError ); + CPPUNIT_TEST( testAddFailure ); CPPUNIT_TEST( testStartTest ); CPPUNIT_TEST( testEndTest ); - CPPUNIT_TEST( testWasSuccessfulWithErrors ); - CPPUNIT_TEST( testWasSuccessfulWithFailures ); - CPPUNIT_TEST( testWasSuccessfulWithErrorsAndFailures ); - CPPUNIT_TEST( testWasSuccessfulWithSucessfulTest ); - CPPUNIT_TEST( testSynchronizationAddError ); - CPPUNIT_TEST( testSynchronizationAddFailure ); - CPPUNIT_TEST( testSynchronizationStartTest ); - CPPUNIT_TEST( testSynchronizationEndTest ); - CPPUNIT_TEST( testSynchronizationRunTests ); - CPPUNIT_TEST( testSynchronizationTestErrors ); - CPPUNIT_TEST( testSynchronizationTestFailures ); - CPPUNIT_TEST( testSynchronizationFailures ); - CPPUNIT_TEST( testSynchronizationWasSuccessful ); - CPPUNIT_TEST( testSynchronizationShouldStop ); - CPPUNIT_TEST( testSynchronizationStop ); + CPPUNIT_TEST( testTwoListener ); CPPUNIT_TEST_SUITE_END(); public: @@ -41,60 +26,28 @@ public: virtual void tearDown(); void testConstructor(); - void testStop(); - void testAddTwoErrors(); - void testAddTwoFailures(); + void testAddError(); + void testAddFailure(); void testStartTest(); void testEndTest(); - void testWasSuccessfulWithNoTest(); - void testWasSuccessfulWithErrors(); - void testWasSuccessfulWithFailures(); - void testWasSuccessfulWithErrorsAndFailures(); - void testWasSuccessfulWithSucessfulTest(); - - void testSynchronizationAddError(); - void testSynchronizationAddFailure(); - void testSynchronizationStartTest(); - void testSynchronizationEndTest(); - void testSynchronizationRunTests(); - void testSynchronizationTestErrors(); - void testSynchronizationTestFailures(); - void testSynchronizationErrors(); - void testSynchronizationFailures(); - void testSynchronizationWasSuccessful(); - void testSynchronizationShouldStop(); - void testSynchronizationStop(); + void testNoListener(); + void testTwoListener(); - virtual void locked(); - virtual void unlocked(); + void testRemoveLastListener(); + void testRemoveFrontListener(); private: TestResultTest( const TestResultTest © ); void operator =( const TestResultTest © ); - void checkResult( int failures, - int errors, - int testsRun ); - - void checkFailure( CppUnit::TestFailure *failure, - std::string expectedMessage, - CppUnit::Test *expectedTest, - bool expectedIsError ); - - void checkWasSuccessful( bool shouldBeSuccessful ); - - void checkSynchronization(); - private: CppUnit::TestResult *m_result; - SynchronizedTestResult *m_synchronizedResult; - CppUnit::Test *m_test; - CppUnit::Test *m_test2; - int m_lockCount; - int m_unlockCount; + MockTestListener *m_listener1; + MockTestListener *m_listener2; + CppUnit::Test *m_dummyTest; }; diff --git a/examples/cppunittest/TestSetUpTest.cpp b/examples/cppunittest/TestSetUpTest.cpp index 06671d8..5a4bad8 100644 --- a/examples/cppunittest/TestSetUpTest.cpp +++ b/examples/cppunittest/TestSetUpTest.cpp @@ -19,16 +19,12 @@ TestSetUpTest::~TestSetUpTest() void TestSetUpTest::setUp() { - m_test = new FailingTestCase(); - m_setUp = new SetUp( m_test ); } void TestSetUpTest::tearDown() { - delete m_setUp; - delete m_test; } @@ -36,7 +32,10 @@ void TestSetUpTest::testRun() { CppUnit::TestResult result; - m_setUp->run( &result ); - CPPUNIT_ASSERT( m_setUp->m_setUpCalled ); - CPPUNIT_ASSERT( m_setUp->m_tearDownCalled ); + CppUnit::TestCase test; + MockSetUp setUpTest( &test ); + + setUpTest.run( &result ); + + setUpTest.verify(); } diff --git a/examples/cppunittest/TestSetUpTest.h b/examples/cppunittest/TestSetUpTest.h index 9a843b7..34d7e4d 100644 --- a/examples/cppunittest/TestSetUpTest.h +++ b/examples/cppunittest/TestSetUpTest.h @@ -3,7 +3,6 @@ #include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/TestSetUp.h> -#include "FailingTestCase.h" class TestSetUpTest : public CppUnit::TestCase @@ -16,19 +15,19 @@ public: TestSetUpTest(); virtual ~TestSetUpTest(); - virtual void setUp(); - virtual void tearDown(); + void setUp(); + void tearDown(); void testRun(); private: - class SetUp : public CppUnit::TestSetUp + class MockSetUp : public CppUnit::TestSetUp { public: - SetUp( CppUnit::Test *test ) : - CppUnit::TestSetUp( test ), - m_setUpCalled( false ), - m_tearDownCalled( false ) + MockSetUp( CppUnit::Test *test ) + : CppUnit::TestSetUp( test ) + , m_setUpCalled( false ) + , m_tearDownCalled( false ) { } @@ -42,6 +41,13 @@ private: m_tearDownCalled = true; } + void verify() + { + CPPUNIT_ASSERT( m_setUpCalled ); + CPPUNIT_ASSERT( m_tearDownCalled ); + } + + private: bool m_setUpCalled; bool m_tearDownCalled; }; @@ -50,8 +56,6 @@ private: void operator =( const TestSetUpTest © ); private: - SetUp *m_setUp; - FailingTestCase *m_test; }; diff --git a/examples/cppunittest/TestSuiteTest.cpp b/examples/cppunittest/TestSuiteTest.cpp index 61de964..d22e39a 100644 --- a/examples/cppunittest/TestSuiteTest.cpp +++ b/examples/cppunittest/TestSuiteTest.cpp @@ -1,7 +1,7 @@ #include "CoreSuite.h" -#include "FailingTestCase.h" #include "TestSuiteTest.h" #include <cppunit/TestResult.h> +#include "MockTestCase.h" CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TestSuiteTest, @@ -22,14 +22,12 @@ void TestSuiteTest::setUp() { m_suite = new CppUnit::TestSuite(); - m_result = new CppUnit::TestResult(); } void TestSuiteTest::tearDown() { - delete m_result; delete m_suite; } @@ -53,59 +51,76 @@ TestSuiteTest::testCountTestCasesWithNoTest() void TestSuiteTest::testCountTestCasesWithTwoTests() { - m_suite->addTest( new CppUnit::TestCase( "test1" ) ); - m_suite->addTest( new CppUnit::TestCase( "test2" ) ); + MockTestCase *case1 = new MockTestCase( "test1" ); + case1->setExpectedCountTestCasesCall(); + MockTestCase *case2 = new MockTestCase( "test2" ); + case2->setExpectedCountTestCasesCall(); + m_suite->addTest( case1 ); + m_suite->addTest( case2 ); CPPUNIT_ASSERT_EQUAL( 2, m_suite->countTestCases() ); + case1->verify(); + case2->verify(); } void TestSuiteTest::testCountTestCasesWithSubSuite() { + MockTestCase *case1 = new MockTestCase( "test1" ); + case1->setExpectedCountTestCasesCall(); + MockTestCase *case2 = new MockTestCase( "test2" ); + case2->setExpectedCountTestCasesCall(); + MockTestCase *case3 = new MockTestCase( "test3" ); + case3->setExpectedCountTestCasesCall(); CppUnit::TestSuite *subSuite = new CppUnit::TestSuite( "SubSuite"); - subSuite->addTest( new CppUnit::TestCase( "test1" ) ); - subSuite->addTest( new CppUnit::TestCase( "test2" ) ); - - m_suite->addTest( new CppUnit::TestCase( "test3" ) ); + subSuite->addTest( case1 ); + subSuite->addTest( case2 ); + m_suite->addTest( case3 ); m_suite->addTest( subSuite ); CPPUNIT_ASSERT_EQUAL( 3, m_suite->countTestCases() ); + case1->verify(); + case2->verify(); + case3->verify(); } void TestSuiteTest::testRunWithOneTest() { - FailingTestCase *test = new FailingTestCase(); - m_suite->addTest( test ); + MockTestCase *case1 = new MockTestCase( "test1" ); + case1->setExpectedRunTestCall(); + m_suite->addTest( case1 ); - m_suite->run( m_result ); - test->verify(); - checkResult( 0, 0, 1 ); + CppUnit::TestResult result; + m_suite->run( &result ); + + case1->verify(); } void TestSuiteTest::testRunWithOneTestAndSubSuite() { + MockTestCase *case1 = new MockTestCase( "test1" ); + case1->setExpectedRunTestCall(); + MockTestCase *case2 = new MockTestCase( "test2" ); + case2->setExpectedRunTestCall(); + MockTestCase *case3 = new MockTestCase( "test3" ); + case3->setExpectedRunTestCall(); CppUnit::TestSuite *subSuite = new CppUnit::TestSuite( "SubSuite"); - - FailingTestCase *test2 = new FailingTestCase(); - subSuite->addTest( test2 ); - - FailingTestCase *test3 = new FailingTestCase(); - subSuite->addTest( test3 ); + subSuite->addTest( case1 ); + subSuite->addTest( case2 ); + m_suite->addTest( case3 ); + m_suite->addTest( subSuite); - FailingTestCase *test = new FailingTestCase(); - m_suite->addTest( test ); - m_suite->addTest( subSuite ); + CppUnit::TestResult result; + m_suite->run( &result ); - m_suite->run( m_result ); - checkResult( 0, 0, 3 ); - test->verify(); - test2->verify(); - test3->verify(); + case1->verify(); + case2->verify(); + case3->verify(); } @@ -125,14 +140,3 @@ TestSuiteTest::testDeleteContents() m_suite->deleteContents(); CPPUNIT_ASSERT_EQUAL( 0, int(m_suite->getTests().size()) ); } - - -void -TestSuiteTest::checkResult( int failures, - int errors, - int testsRun ) -{ - CPPUNIT_ASSERT_EQUAL( testsRun, m_result->runTests() ); - CPPUNIT_ASSERT_EQUAL( errors, m_result->testErrors() ); - CPPUNIT_ASSERT_EQUAL( failures, m_result->testFailures() ); -} diff --git a/examples/cppunittest/TestSuiteTest.h b/examples/cppunittest/TestSuiteTest.h index f39a652..fb40f58 100644 --- a/examples/cppunittest/TestSuiteTest.h +++ b/examples/cppunittest/TestSuiteTest.h @@ -41,13 +41,8 @@ private: TestSuiteTest( const TestSuiteTest © ); void operator =( const TestSuiteTest © ); - void checkResult( int failures, - int errors, - int testsRun ); - private: CppUnit::TestSuite *m_suite; - CppUnit::TestResult *m_result; }; diff --git a/examples/cppunittest/XmlOutputterTest.cpp b/examples/cppunittest/XmlOutputterTest.cpp index d8326bc..f3cdeeb 100644 --- a/examples/cppunittest/XmlOutputterTest.cpp +++ b/examples/cppunittest/XmlOutputterTest.cpp @@ -1,4 +1,5 @@ -#include <cppunit/TestResult.h> +#include <cppunit/XmlOutputter.h> +#include <cppunit/TestFailure.h> #include <cppunit/XmlOutputter.h> #include "OutputSuite.h" #include "XmlOutputterTest.h" @@ -23,12 +24,18 @@ XmlOutputterTest::~XmlOutputterTest() void XmlOutputterTest::setUp() { + m_dummyTests.clear(); + m_result = new CppUnit::TestResultCollector(); } void XmlOutputterTest::tearDown() { + delete m_result; + for ( int index =0; index < m_dummyTests.size(); ++index ) + delete m_dummyTests[index]; + m_dummyTests.clear(); } @@ -109,10 +116,8 @@ XmlOutputterTest::testNodeWithContentAndChildToString() void XmlOutputterTest::testWriteXmlResultWithNoTest() { - CppUnit::TestResult result; - CppUnit::OStringStream stream; - CppUnit::XmlOutputter outputter( &result, stream ); + CppUnit::XmlOutputter outputter( m_result, stream ); outputter.write(); std::string actualXml = stream.str(); @@ -134,16 +139,10 @@ XmlOutputterTest::testWriteXmlResultWithNoTest() void XmlOutputterTest::testWriteXmlResultWithOneFailure() { - CppUnit::TestResult result; - CppUnit::TestCase test1( "test1" ); - result.startTest( &test1 ); - CppUnit::SourceLine sourceLine( "test.cpp", 3 ); - result.addFailure( &test1, new CppUnit::Exception( "message failure1", - sourceLine ) ); - result.endTest( &test1 ); + addTestFailure( "test1", "message failure1", CppUnit::SourceLine( "test.cpp", 3 ) ); CppUnit::OStringStream stream; - CppUnit::XmlOutputter outputter( &result, stream ); + CppUnit::XmlOutputter outputter( m_result, stream ); outputter.write(); std::string actualXml = stream.str(); @@ -175,14 +174,10 @@ XmlOutputterTest::testWriteXmlResultWithOneFailure() void XmlOutputterTest::testWriteXmlResultWithOneError() { - CppUnit::TestResult result; - CppUnit::TestCase test1( "test1" ); - result.startTest( &test1 ); - result.addError( &test1, new CppUnit::Exception( "message error1" ) ); - result.endTest( &test1 ); + addTestError( "test1", "message error1" ); CppUnit::OStringStream stream; - CppUnit::XmlOutputter outputter( &result, stream ); + CppUnit::XmlOutputter outputter( m_result, stream ); outputter.write(); std::string actualXml = stream.str(); @@ -210,13 +205,10 @@ XmlOutputterTest::testWriteXmlResultWithOneError() void XmlOutputterTest::testWriteXmlResultWithOneSucess() { - CppUnit::TestResult result; - CppUnit::TestCase test1( "test1" ); - result.startTest( &test1 ); - result.endTest( &test1 ); + addTest( "test1" ); CppUnit::OStringStream stream; - CppUnit::XmlOutputter outputter( &result, stream ); + CppUnit::XmlOutputter outputter( m_result, stream ); outputter.write(); std::string actualXml = stream.str(); @@ -242,36 +234,16 @@ XmlOutputterTest::testWriteXmlResultWithOneSucess() void XmlOutputterTest::testWriteXmlResultWithThreeFailureTwoErrorsAndTwoSucess() { - CppUnit::TestCase test1( "test1" ); - CppUnit::TestCase test2( "test2" ); - CppUnit::TestCase test3( "test3" ); - CppUnit::TestCase test4( "test4" ); - CppUnit::TestCase test5( "test5" ); - CppUnit::TestCase test6( "test6" ); - CppUnit::TestCase test7( "test7" ); - CppUnit::TestResult result; - result.startTest( &test1 ); - result.addFailure( &test1, new CppUnit::Exception( "failure1" ) ); - result.endTest( &test1 ); - result.startTest( &test2 ); - result.addError( &test2, new CppUnit::Exception( "error1" ) ); - result.endTest( &test2 ); - result.startTest( &test3 ); - result.addFailure( &test3, new CppUnit::Exception( "failure2" ) ); - result.endTest( &test3 ); - result.startTest( &test4 ); - result.addFailure( &test4, new CppUnit::Exception( "failure3" ) ); - result.endTest( &test4 ); - result.startTest( &test5 ); - result.endTest( &test5 ); - result.startTest( &test6 ); - result.addError( &test6, new CppUnit::Exception( "error2" ) ); - result.endTest( &test6 ); - result.startTest( &test7 ); - result.endTest( &test7 ); + addTestFailure( "test1", "failure1" ); + addTestError( "test2", "error1" ); + addTestFailure( "test3", "failure2" ); + addTestFailure( "test4", "failure3" ); + addTest( "test5" ); + addTestError( "test6", "error2" ); + addTest( "test7" ); CppUnit::OStringStream stream; - CppUnit::XmlOutputter outputter( &result, stream ); + CppUnit::XmlOutputter outputter( m_result, stream ); outputter.write(); std::string actualXml = stream.str(); @@ -320,4 +292,56 @@ XmlOutputterTest::testWriteXmlResultWithThreeFailureTwoErrorsAndTwoSucess() "</Statistics>" "</TestRun>"; CPPUNITTEST_ASSERT_XML_EQUAL( expectedXml, actualXml ); -}
\ No newline at end of file +} + + +void +XmlOutputterTest::addTest( std::string testName ) +{ + CppUnit::Test *test = makeDummyTest( testName ); + m_result->startTest( test ); + m_result->endTest( test ); +} + + +void +XmlOutputterTest::addTestFailure( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine ) +{ + addGenericTestFailure( testName, message, sourceLine, false ); +} + + +void +XmlOutputterTest::addTestError( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine ) +{ + addGenericTestFailure( testName, message, sourceLine, true ); +} + + +void +XmlOutputterTest::addGenericTestFailure( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine, + bool isError ) +{ + CppUnit::Test *test = makeDummyTest( testName ); + m_result->startTest( test ); + CppUnit::TestFailure failure( test, + new CppUnit::Exception( message, sourceLine ), + isError ); + m_result->addFailure( failure ); + m_result->endTest( test ); +} + + +CppUnit::Test * +XmlOutputterTest::makeDummyTest( std::string testName ) +{ + CppUnit::Test *test = new CppUnit::TestCase( testName ); + m_dummyTests.push_back( test ); + return test; +} diff --git a/examples/cppunittest/XmlOutputterTest.h b/examples/cppunittest/XmlOutputterTest.h index f515d9f..a89c4e8 100644 --- a/examples/cppunittest/XmlOutputterTest.h +++ b/examples/cppunittest/XmlOutputterTest.h @@ -2,7 +2,10 @@ #define CPPUNITEST_XMLTESTRESULTOUTPUTTERTEST_H #include <cppunit/extensions/HelperMacros.h> +#include <cppunit/Test.h> #include <cppunit/TestFailure.h> +#include <cppunit/TestResultCollector.h> +#include <deque> /*! \class XmlOutputterTest @@ -62,7 +65,23 @@ private: int error, int failure ); + void addTest( std::string testName ); + void addTestFailure( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine = CppUnit::SourceLine() ); + void addTestError( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine = CppUnit::SourceLine() ); + void addGenericTestFailure( std::string testName, + std::string message, + CppUnit::SourceLine sourceLine, + bool isError ); + + CppUnit::Test *makeDummyTest( std::string testName ); + private: + CppUnit::TestResultCollector *m_result; + std::deque<CppUnit::Test *> m_dummyTests; }; diff --git a/examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp b/examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp index f733a31..0bdafe8 100644 --- a/examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp +++ b/examples/msvc6/CppUnitTestApp/CppUnitTestApp.dsp @@ -144,15 +144,6 @@ SOURCE=..\..\cppunittest\TestFailureTest.h # End Source File # Begin Source File -SOURCE=..\..\cppunittest\TestListenerTest.cpp -# SUBTRACT CPP /YX /Yc /Yu -# End Source File -# Begin Source File - -SOURCE=..\..\cppunittest\TestListenerTest.h -# End Source File -# Begin Source File - SOURCE=..\..\cppunittest\TestResultTest.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -254,16 +245,16 @@ SOURCE=..\..\cppunittest\BaseTestCase.h # End Source File # Begin Source File -SOURCE=..\..\cppunittest\FailingTestCase.cpp -# SUBTRACT CPP /YX /Yc /Yu +SOURCE=..\..\cppunittest\FailureException.h # End Source File # Begin Source File -SOURCE=..\..\cppunittest\FailingTestCase.h +SOURCE=..\..\cppunittest\MockTestCase.cpp +# SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File -SOURCE=..\..\cppunittest\FailureException.h +SOURCE=..\..\cppunittest\MockTestCase.h # End Source File # Begin Source File @@ -332,6 +323,15 @@ SOURCE=..\..\cppunittest\OutputSuite.h # End Source File # Begin Source File +SOURCE=..\..\cppunittest\TestResultCollectorTest.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\cppunittest\TestResultCollectorTest.h +# End Source File +# Begin Source File + SOURCE=..\..\cppunittest\XmlOutputterTest.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -428,17 +428,7 @@ InputName=testrunner # Begin Source File SOURCE=..\..\..\lib\testrunnercd.dll - -!IF "$(CFG)" == "CppUnitTestApp - Win32 Release" - # PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "CppUnitTestApp - Win32 Debug" - -# PROP Exclude_From_Build 1 - -!ENDIF - # End Source File # Begin Source File diff --git a/include/cppunit/CompilerOutputter.h b/include/cppunit/CompilerOutputter.h index 67e0177..eb15875 100644 --- a/include/cppunit/CompilerOutputter.h +++ b/include/cppunit/CompilerOutputter.h @@ -2,6 +2,7 @@ #define CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H #include <cppunit/Portability.h> +#include <cppunit/Outputter.h> #include <vector> #include <iostream> @@ -12,26 +13,26 @@ class Exception; class SourceLine; class Test; class TestFailure; -class TestResult; +class TestResultCollector; /*! \class CompilerOutputter * \brief This class implements output test result in a compiler compatible format. */ -class CompilerOutputter +class CompilerOutputter : public Outputter { public: /*! Constructs a CompilerOutputter object. */ - CompilerOutputter( TestResult *result, - std::ostream &stream ); + CompilerOutputter( TestResultCollector *result, + std::ostream &stream ); /// Destructor. virtual ~CompilerOutputter(); - static CompilerOutputter *defaultOutputter( TestResult *result, - std::ostream &stream ); + static CompilerOutputter *defaultOutputter( TestResultCollector *result, + std::ostream &stream ); - virtual void write( ); + void write(); virtual void printSucess(); virtual void printFailureReport(); @@ -57,7 +58,7 @@ private: static Lines splitMessageIntoLines( std::string message ); private: - TestResult *m_result; + TestResultCollector *m_result; std::ostream &m_stream; }; diff --git a/include/cppunit/Makefile.am b/include/cppunit/Makefile.am index 6f0916d..be74e73 100644 --- a/include/cppunit/Makefile.am +++ b/include/cppunit/Makefile.am @@ -11,6 +11,7 @@ libcppunitinclude_HEADERS = \ CompilerOutputter.h \ Exception.h \ NotEqualException.h \ + Outputter.h \ Portability.h \ SourceLine.h \ Test.h \ @@ -20,7 +21,10 @@ libcppunitinclude_HEADERS = \ TestFailure.h \ TestResult.h \ TestRegistry.h \ + TestResultCollector.h \ + TestSucessListener.h \ TestSuite.h \ + TextTestProgressListener.h \ TextTestResult.h \ TextTestRunner.h \ TestListener.h \ diff --git a/include/cppunit/Outputter.h b/include/cppunit/Outputter.h new file mode 100644 index 0000000..1ff00c1 --- /dev/null +++ b/include/cppunit/Outputter.h @@ -0,0 +1,30 @@ +#ifndef CPPUNIT_OUTPUTTER_H +#define CPPUNIT_OUTPUTTER_H + +#include <cppunit/Portability.h> + + +namespace CppUnit +{ + +/*! This class represents an abstract outputter. + */ +class Outputter +{ +public: + /// Destructor. + virtual ~Outputter() {} + + virtual void write() =0; +}; + + + +// Inlines methods for Outputter: +// ------------------------------ + + +} // namespace CppUnit + + +#endif // CPPUNIT_OUTPUTTER_H diff --git a/include/cppunit/Portability.h b/include/cppunit/Portability.h index 52d26bc..881980c 100644 --- a/include/cppunit/Portability.h +++ b/include/cppunit/Portability.h @@ -45,7 +45,9 @@ #if CPPUNIT_HAVE_SSTREAM # include <sstream> namespace CppUnit { - typedef std::ostringstream OStringStream; + class OStringStream : public std::ostringstream + { + }; } #else #if CPPUNIT_HAVE_CLASS_STRSTREAM @@ -57,17 +59,17 @@ # endif namespace CppUnit { - class OStringStream : public std::ostrstream - { - public: - std::string str() - { - (*this) << '\0'; - std::string msg(std::ostrstream::str()); - std::ostrstream::freeze(false); - return msg; - } - }; + class OStringStream : public std::ostrstream + { + public: + std::string str() + { + (*this) << '\0'; + std::string msg(std::ostrstream::str()); + std::ostrstream::freeze(false); + return msg; + } + }; } #else # error Cannot define CppUnit::OStringStream. diff --git a/include/cppunit/SynchronizedObject.h b/include/cppunit/SynchronizedObject.h new file mode 100644 index 0000000..3e8496d --- /dev/null +++ b/include/cppunit/SynchronizedObject.h @@ -0,0 +1,78 @@ +#ifndef CPPUNIT_SYNCHRONIZEDOBJECT_H +#define CPPUNIT_SYNCHRONIZEDOBJECT_H + +#include <cppunit/Portability.h> + + +namespace CppUnit +{ + +/*! Base class for synchronized object. + * + * Synchronized object are object which members are used concurrently by mutiple + * threads.* + * + * This class define the class SynchronizationObject which must be subclassed + * to implement an actual lock. + * + * Each instance of this class holds a pointer on a lock object. + * + * See src/msvc6/MfcSynchronizedObject.h for an example. + */ +class SynchronizedObject +{ +public: + class SynchronizationObject + { + public: + SynchronizationObject() {} + virtual ~SynchronizationObject() {} + + virtual void lock() {} + virtual void unlock() {} + }; + + /*! Constructs a SynchronizedObject object. + */ + SynchronizedObject( SynchronizationObject *syncObject =0 ); + + /// Destructor. + virtual ~SynchronizedObject(); + +protected: + class ExclusiveZone + { + SynchronizationObject *m_syncObject; + + public: + ExclusiveZone( SynchronizationObject *syncObject ) + : m_syncObject( syncObject ) + { + m_syncObject->lock(); + } + + ~ExclusiveZone() + { + m_syncObject->unlock (); + } + }; + + virtual void setSynchronizationObject( SynchronizationObject *syncObject ); + +protected: + SynchronizationObject *m_syncObject; + +private: + /// Prevents the use of the copy constructor. + SynchronizedObject( const SynchronizedObject © ); + + /// Prevents the use of the copy operator. + void operator =( const SynchronizedObject © ); +}; + + + +} // namespace CppUnit + + +#endif // CPPUNIT_SYNCHRONIZEDOBJECT_H diff --git a/include/cppunit/TestAssert.h b/include/cppunit/TestAssert.h index ff156d7..4c1478b 100644 --- a/include/cppunit/TestAssert.h +++ b/include/cppunit/TestAssert.h @@ -65,13 +65,15 @@ namespace CppUnit { template <class T> void assertEquals( const T& expected, const T& actual, - SourceLine sourceLine ) + SourceLine sourceLine, + const std::string &message ="" ) { if ( !assertion_traits<T>::equal(expected,actual) ) // lazy toString conversion... { Asserter::failNotEqual( assertion_traits<T>::toString(expected), assertion_traits<T>::toString(actual), - sourceLine ); + sourceLine, + message ); } } @@ -109,7 +111,7 @@ namespace CppUnit { */ #define CPPUNIT_ASSERT_MESSAGE(message,condition) \ ( ::CppUnit::Asserter::failIf( !(condition), \ - message, \ + (message), \ CPPUNIT_SOURCELINE() ) ) /** Failure with a user specified message. @@ -134,6 +136,11 @@ namespace CppUnit { ( ::CppUnit::TestAssert::assertEquals( (expected), \ (actual), \ CPPUNIT_SOURCELINE() ) ) +#define CPPUNIT_ASSERT_EQUAL_MESSAGE(expected,actual,message) \ + ( ::CppUnit::TestAssert::assertEquals( (expected), \ + (actual), \ + CPPUNIT_SOURCELINE(), \ + (message) ) ) #endif /// Macro for primitive value comparisons diff --git a/include/cppunit/TestCase.h b/include/cppunit/TestCase.h index 1c2ee53..c40198c 100644 --- a/include/cppunit/TestCase.h +++ b/include/cppunit/TestCase.h @@ -93,37 +93,37 @@ class TestCase : public Test { public: - TestCase (std::string Name); + TestCase( std::string Name ); //! \internal - TestCase (); - ~TestCase (); + TestCase(); + ~TestCase(); - virtual void run (TestResult *result); - virtual int countTestCases () const; - std::string getName () const; - std::string toString () const; + virtual void run(TestResult *result); + virtual int countTestCases() const; + std::string getName() const; + std::string toString() const; //! FIXME: what is this for? - virtual TestResult *run (); + virtual TestResult *run(); // FIXME: move back to class TestFixture, in future. - virtual void setUp (); - virtual void tearDown (); + virtual void setUp(); + virtual void tearDown(); protected: //! FIXME: this should probably be pure virtual. - virtual void runTest (); + virtual void runTest(); //! Create TestResult for the run(void) method. - TestResult *defaultResult (); + TestResult *defaultResult(); private: - TestCase (const TestCase& other); - TestCase& operator= (const TestCase& other); + TestCase( const TestCase &other ); + TestCase &operator=( const TestCase &other ); private: - const std::string m_name; + const std::string m_name; }; } // namespace CppUnit diff --git a/include/cppunit/TestFailure.h b/include/cppunit/TestFailure.h index 2041c8c..61f4018 100644 --- a/include/cppunit/TestFailure.h +++ b/include/cppunit/TestFailure.h @@ -28,17 +28,19 @@ public: virtual ~TestFailure (); - Test *failedTest() const; + virtual Test *failedTest() const; - Exception *thrownException() const; + virtual Exception *thrownException() const; - SourceLine sourceLine() const; + virtual SourceLine sourceLine() const; - bool isError() const; + virtual bool isError() const; - std::string failedTestName() const; + virtual std::string failedTestName() const; - std::string toString() const; + virtual std::string toString() const; + + virtual TestFailure *clone() const; protected: Test *m_failedTest; diff --git a/include/cppunit/TestListener.h b/include/cppunit/TestListener.h index 738aaa5..d9d482a 100644 --- a/include/cppunit/TestListener.h +++ b/include/cppunit/TestListener.h @@ -1,6 +1,8 @@ #ifndef CPPUNIT_TESTLISTENER_H // -*- C++ -*- #define CPPUNIT_TESTLISTENER_H +#include <cppunit/Portability.h> + namespace CppUnit { @@ -9,18 +11,28 @@ class Test; class TestFailure; -/*! \brief A listener for test progress. +/*! TestListener is the interface implemented by classes which want to be notified + * of the progress and result of a test run. * * \see TestResult */ class TestListener { public: - virtual ~TestListener() {} - - virtual void startTest( Test *test ) {} - virtual void addFailure( TestFailure *failure ) {} - virtual void endTest( Test *test ) {} + virtual ~TestListener() {} + + /// Called when just before a TestCase is run. + virtual void startTest( Test *test ) {} + + /*! Called when a failure occurs while running a test. + * \see TestFailure. + * \warning \a failure is a temporary object that is destroyed after the + * method call. Use TestFailure::clone() to create a duplicate. + */ + virtual void addFailure( const TestFailure &failure ) {} + + /// Called just after a TestCase was run (even if a failure occured). + virtual void endTest( Test *test ) {} }; diff --git a/include/cppunit/TestResult.h b/include/cppunit/TestResult.h index 855be27..9c2930a 100644 --- a/include/cppunit/TestResult.h +++ b/include/cppunit/TestResult.h @@ -1,13 +1,14 @@ #ifndef CPPUNIT_TESTRESULT_H #define CPPUNIT_TESTRESULT_H -#include <cppunit/TestFailure.h> +#include <cppunit/SynchronizedObject.h> #include <deque> namespace CppUnit { class Exception; class Test; +class TestFailure; class TestListener; @@ -15,6 +16,8 @@ class TestListener; * A TestResult collects the results of executing a test case. It is an * instance of the Collecting Parameter pattern. * + * FIXME: NEED UPDATE (main responsibilty is to act as an event manager) + * * The test framework distinguishes between failures and errors. * A failure is anticipated and checked for with assertions. Errors are * unanticipated problems signified by exceptions that are not generated @@ -28,82 +31,39 @@ class TestListener; * and make sure that you create an instance of ExclusiveZone at the * beginning of each method. * - * \see Test + * \see Test, TestResultCollector */ -class TestResult +class TestResult : protected SynchronizedObject { - public: - typedef std::deque<TestFailure *> TestFailures; - typedef std::deque<Test *> Tests; - - class SynchronizationObject - { - public: - SynchronizationObject() {} - virtual ~SynchronizationObject() {} - - virtual void lock() {} - virtual void unlock() {} - }; - - TestResult( SynchronizationObject *syncObject =0 ); - virtual ~TestResult(); - - virtual void reset(); - - virtual void addError( Test *test, Exception *e ); - virtual void addFailure( Test *test, Exception *e ); - virtual void startTest( Test *test ); - virtual void endTest( Test *test ); - virtual int runTests() const; - virtual int testErrors() const; - virtual int testFailures() const; - virtual int testFailuresTotal() const; - virtual bool wasSuccessful() const; - virtual bool shouldStop() const; - - virtual void stop(); - - virtual const TestFailures& failures() const; - virtual const Tests &tests() const; - - virtual void addListener( TestListener *listener ); - virtual void removeListener( TestListener *listener ); - - - class ExclusiveZone - { - SynchronizationObject *m_syncObject; - - public: - ExclusiveZone( SynchronizationObject *syncObject ) - : m_syncObject( syncObject ) - { - m_syncObject->lock(); - } - - ~ExclusiveZone() - { - m_syncObject->unlock (); - } - }; - - protected: - virtual void setSynchronizationObject( SynchronizationObject *syncObject ); - virtual void addFailure( TestFailure *failure ); - - Tests m_tests; - TestFailures m_failures; - typedef std::deque<TestListener *> TestListeners; - TestListeners m_listeners; - int m_testErrors; - bool m_stop; - SynchronizationObject *m_syncObject; - - private: - TestResult( const TestResult &other ); - TestResult &operator =( const TestResult &other ); +public: + TestResult( SynchronizationObject *syncObject = 0 ); + virtual ~TestResult(); + + virtual void addListener( TestListener *listener ); + virtual void removeListener( TestListener *listener ); + + virtual void reset(); + virtual void stop(); + + virtual bool shouldStop() const; + + virtual void startTest( Test *test ); + virtual void addError( Test *test, Exception *e ); + virtual void addFailure( Test *test, Exception *e ); + virtual void endTest( Test *test ); + +protected: + void addFailure( const TestFailure &failure ); + +protected: + typedef std::deque<TestListener *> TestListeners; + TestListeners m_listeners; + bool m_stop; + +private: + TestResult( const TestResult &other ); + TestResult &operator =( const TestResult &other ); }; } // namespace CppUnit diff --git a/include/cppunit/TestResultCollector.h b/include/cppunit/TestResultCollector.h new file mode 100644 index 0000000..bd2f0b1 --- /dev/null +++ b/include/cppunit/TestResultCollector.h @@ -0,0 +1,66 @@ +#ifndef CPPUNIT_TESTRESULTCOLLECTOR_H +#define CPPUNIT_TESTRESULTCOLLECTOR_H + +#include <cppunit/TestSucessListener.h> +#include <deque> + + +namespace CppUnit +{ + + +/*! + * A TestResultCollector is a TestListener which collects the results of executing + * a test case. It is an instance of the Collecting Parameter pattern. + * + * The test framework distinguishes between failures and errors. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems signified by exceptions that are not generated + * by the framework. + */ +class TestResultCollector : public TestSucessListener +{ +public: + typedef std::deque<TestFailure *> TestFailures; + typedef std::deque<Test *> Tests; + + + /*! Constructs a TestResultCollector object. + */ + TestResultCollector( SynchronizationObject *syncObject = 0 ); + + /// Destructor. + virtual ~TestResultCollector(); + + void startTest( Test *test ); + void addFailure( const TestFailure &failure ); + + virtual void reset(); + + virtual int runTests() const; + virtual int testErrors() const; + virtual int testFailures() const; + virtual int testFailuresTotal() const; + + virtual const TestFailures& failures() const; + virtual const Tests &tests() const; + +protected: + Tests m_tests; + TestFailures m_failures; + int m_testErrors; + +private: + /// Prevents the use of the copy constructor. + TestResultCollector( const TestResultCollector © ); + + /// Prevents the use of the copy operator. + void operator =( const TestResultCollector © ); +}; + + + +} // namespace CppUnit + + +#endif // CPPUNIT_TESTRESULTCOLLECTOR_H diff --git a/include/cppunit/TestSucessListener.h b/include/cppunit/TestSucessListener.h new file mode 100644 index 0000000..20e1d6b --- /dev/null +++ b/include/cppunit/TestSucessListener.h @@ -0,0 +1,39 @@ +#ifndef CPPUNIT_TESTSUCESSLISTENER_H +#define CPPUNIT_TESTSUCESSLISTENER_H + +#include <cppunit/SynchronizedObject.h> +#include <cppunit/TestListener.h> + + +namespace CppUnit +{ + +/*! A TestSucessListener is a TestListener which check if any test case failed. + */ +class TestSucessListener : public TestListener, + public SynchronizedObject +{ +public: + /*! Constructs a TestSucessListener object. + */ + TestSucessListener( SynchronizationObject *syncObject = 0 ); + + /// Destructor. + virtual ~TestSucessListener(); + + virtual void reset(); + + void addFailure( const TestFailure &failure ); + + /// Returns whether the entire test was successful or not. + virtual bool wasSuccessful() const; + +private: + bool m_sucess; +}; + + +} // namespace CppUnit + + +#endif // CPPUNIT_TESTSUCESSLISTENER_H diff --git a/include/cppunit/TextOutputter.h b/include/cppunit/TextOutputter.h new file mode 100644 index 0000000..22010a1 --- /dev/null +++ b/include/cppunit/TextOutputter.h @@ -0,0 +1,59 @@ +#ifndef CPPUNIT_TEXTOUTPUTTER_H +#define CPPUNIT_TEXTOUTPUTTER_H + +#include <cppunit/Portability.h> +#include <cppunit/Outputter.h> +#include <iostream> + +namespace CppUnit +{ + +class Exception; +class SourceLine; +class TestResultCollector; +class TestFailure; + + +/*! Print a TestResultCollector in text format. + */ +class TextOutputter : public Outputter +{ +public: + TextOutputter( TestResultCollector *result, + std::ostream &stream ); + + /// Destructor. + virtual ~TextOutputter(); + + void write(); + virtual void printFailures(); + virtual void printHeader(); + + virtual void printFailure( TestFailure *failure, + int failureNumber ); + virtual void printFailureListMark( int failureNumber ); + virtual void printFailureTestName( TestFailure *failure ); + virtual void printFailureType( TestFailure *failure ); + virtual void printFailureLocation( SourceLine sourceLine ); + virtual void printFailureDetail( Exception *thrownException ); + virtual void printFailureWarning(); + virtual void printStatistics(); + +protected: + TestResultCollector *m_result; + std::ostream &m_stream; + +private: + /// Prevents the use of the copy constructor. + TextOutputter( const TextOutputter © ); + + /// Prevents the use of the copy operator. + void operator =( const TextOutputter © ); +}; + + + +} // namespace CppUnit + + +#endif // CPPUNIT_TEXTOUTPUTTER_H diff --git a/include/cppunit/TextTestProgressListener.h b/include/cppunit/TextTestProgressListener.h new file mode 100644 index 0000000..c8911cd --- /dev/null +++ b/include/cppunit/TextTestProgressListener.h @@ -0,0 +1,42 @@ +#ifndef CPPUNIT_TEXTTESTPROGRESSLISTENER_H +#define CPPUNIT_TEXTTESTPROGRESSLISTENER_H + +#include <cppunit/TestListener.h> + + +namespace CppUnit +{ + +/*! \class TextTestProgressListener + * \brief This class represents + */ +class TextTestProgressListener : public TestListener +{ +public: + /*! Constructs a TextTestProgressListener object. + */ + TextTestProgressListener(); + + /// Destructor. + virtual ~TextTestProgressListener(); + + void startTest( Test *test ); + void addFailure( const TestFailure &failure ); + + void done(); + +private: + /// Prevents the use of the copy constructor. + TextTestProgressListener( const TextTestProgressListener © ); + + /// Prevents the use of the copy operator. + void operator =( const TextTestProgressListener © ); + +private: +}; + + +} // namespace CppUnit + + +#endif // CPPUNIT_TEXTTESTPROGRESSLISTENER_H diff --git a/include/cppunit/TextTestResult.h b/include/cppunit/TextTestResult.h index 4558fab..dd2cf31 100644 --- a/include/cppunit/TextTestResult.h +++ b/include/cppunit/TextTestResult.h @@ -2,6 +2,7 @@ #define CPPUNIT_TEXTTESTRESULT_H #include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> #include <iostream> namespace CppUnit { @@ -10,31 +11,37 @@ class SourceLine; class Exception; class Test; -class TextTestResult : public TestResult +/*! Holds printable test result (DEPRECATED). + * + * Use class TextTestProgressListener and TextOutputter instead. + */ +class TextTestResult : public TestResult, + public TestResultCollector { - public: - virtual void addError( Test *test, Exception *e ); - virtual void addFailure( Test *test, Exception *e ); - virtual void startTest( Test *test ); - virtual void print( std::ostream &stream ); - virtual void printFailures( std::ostream &stream ); - virtual void printHeader( std::ostream &stream ); - - virtual void printFailure( TestFailure *failure, - int failureNumber, - std::ostream &stream ); - virtual void printFailureListMark( int failureNumber, - std::ostream &stream ); - virtual void printFailureTestName( TestFailure *failure, - std::ostream &stream ); - virtual void printFailureType( TestFailure *failure, - std::ostream &stream ); - virtual void printFailureLocation( SourceLine sourceLine, - std::ostream &stream ); - virtual void printFailureDetail( Exception *thrownException, +public: + TextTestResult(); + + virtual void addFailure( const TestFailure &failure ); + virtual void startTest( Test *test ); + virtual void print( std::ostream &stream ); + virtual void printFailures( std::ostream &stream ); + virtual void printHeader( std::ostream &stream ); + + virtual void printFailure( TestFailure *failure, + int failureNumber, + std::ostream &stream ); + virtual void printFailureListMark( int failureNumber, + std::ostream &stream ); + virtual void printFailureTestName( TestFailure *failure, std::ostream &stream ); - virtual void printFailureWarning( std::ostream &stream ); - virtual void printStatistics( std::ostream &stream ); + virtual void printFailureType( TestFailure *failure, + std::ostream &stream ); + virtual void printFailureLocation( SourceLine sourceLine, + std::ostream &stream ); + virtual void printFailureDetail( Exception *thrownException, + std::ostream &stream ); + virtual void printFailureWarning( std::ostream &stream ); + virtual void printStatistics( std::ostream &stream ); }; /** insertion operator for easy output */ diff --git a/include/cppunit/TextTestRunner.h b/include/cppunit/TextTestRunner.h index e44f68d..b005487 100644 --- a/include/cppunit/TextTestRunner.h +++ b/include/cppunit/TextTestRunner.h @@ -6,13 +6,17 @@ namespace CppUnit { +class Outputter; class Test; class TestSuite; -class TextTestResult; +class TextOutputter; +class TestResult; +class TestResultCollector; /** * A text mode test runner. * + * FIXME: need update * The test runner manage the life cycle of the added tests. * * The test runner can run only one of the added tests or all the tests. @@ -31,7 +35,11 @@ class TextTestResult; class TextTestRunner { public: - TextTestRunner( TextTestResult *result =0 ); + /*! Constructs a new text runner. + * \param outputter used to print text result. Owned by the runner. + */ + TextTestRunner( Outputter *outputter =NULL ); + virtual ~TextTestRunner(); bool run( std::string testName ="", @@ -40,7 +48,11 @@ public: void addTest( Test *test ); - TextTestResult *result(); + void setOutputter( Outputter *outputter ); + + TestResultCollector &result() const; + + TestResult &eventManager() const; protected: bool runTest( Test *test ); @@ -49,8 +61,11 @@ protected: void printResult( bool doPrintResult ); Test *findTestByName( std::string name ) const; + TestSuite *m_suite; - TextTestResult *m_result; + TestResultCollector *m_result; + TestResult *m_eventManager; + Outputter *m_outputter; }; } // namespace CppUnit diff --git a/include/cppunit/XmlOutputter.h b/include/cppunit/XmlOutputter.h index 6aeed92..fbe6783 100644 --- a/include/cppunit/XmlOutputter.h +++ b/include/cppunit/XmlOutputter.h @@ -2,6 +2,7 @@ #define CPPUNIT_XMLTESTRESULTOUTPUTTER_H #include <cppunit/Portability.h> +#include <cppunit/Outputter.h> #include <deque> #include <iostream> #include <map> @@ -13,18 +14,18 @@ namespace CppUnit class Test; class TestFailure; -class TestResult; +class TestResultCollector; -/*! This class ouputs a TestResult in XML format. +/*! Outputs a TestResultCollector in XML format. */ -class XmlOutputter +class XmlOutputter : public Outputter { public: /*! Constructs a XmlOutputter object. */ - XmlOutputter( TestResult *result, - std::ostream &stream ); + XmlOutputter( TestResultCollector *result, + std::ostream &stream ); /// Destructor. virtual ~XmlOutputter(); @@ -100,7 +101,7 @@ protected: virtual void fillFailedTestsMap( FailedTests &failedTests ); protected: - TestResult *m_result; + TestResultCollector *m_result; std::ostream &m_stream; private: diff --git a/include/cppunit/extensions/HelperMacros.h b/include/cppunit/extensions/HelperMacros.h index 08307eb..637268d 100644 --- a/include/cppunit/extensions/HelperMacros.h +++ b/include/cppunit/extensions/HelperMacros.h @@ -83,8 +83,8 @@ * You need to add in an implementation file: * * \code - * CPPUNIT_TEST_SUITE_REGISTRATION( String<char> ); - * CPPUNIT_TEST_SUITE_REGISTRATION( String<wchar_t> ); + * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<char> ); + * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<wchar_t> ); * \endcode */ diff --git a/src/cppunit/CompilerOutputter.cpp b/src/cppunit/CompilerOutputter.cpp index c9f308e..54c881a 100644 --- a/src/cppunit/CompilerOutputter.cpp +++ b/src/cppunit/CompilerOutputter.cpp @@ -1,7 +1,8 @@ #include <algorithm> #include <cppunit/NotEqualException.h> #include <cppunit/SourceLine.h> -#include <cppunit/TestResult.h> +#include <cppunit/TestFailure.h> +#include <cppunit/TestResultCollector.h> #include <cppunit/CompilerOutputter.h> @@ -10,6 +11,8 @@ namespace CppUnit /** Print TestResult in a compiler compatible format. * + * Note: NEED UPDATE + * * Heres is an example of usage: * \code * int main( int argc, char* argv[] ) { @@ -31,9 +34,8 @@ namespace CppUnit * } * \endcode */ -CompilerOutputter::CompilerOutputter( - TestResult *result, - std::ostream &stream ) : +CompilerOutputter::CompilerOutputter( TestResultCollector *result, + std::ostream &stream ) : m_result( result ), m_stream( stream ) { @@ -46,8 +48,8 @@ CompilerOutputter::~CompilerOutputter() CompilerOutputter * -CompilerOutputter::defaultOutputter( TestResult *result, - std::ostream &stream ) +CompilerOutputter::defaultOutputter( TestResultCollector *result, + std::ostream &stream ) { return new CompilerOutputter( result, stream ); // For automatic adpatation... diff --git a/src/cppunit/Makefile.am b/src/cppunit/Makefile.am index f601f28..a16908c 100644 --- a/src/cppunit/Makefile.am +++ b/src/cppunit/Makefile.am @@ -1,5 +1,5 @@ # -# $Id: Makefile.am,v 1.14 2001-10-07 19:36:47 blep Exp $ +# $Id: Makefile.am,v 1.15 2002-02-28 10:57:20 blep Exp $ # EXTRA_DIST = cppunit.dsw cppunit.dsp @@ -10,19 +10,23 @@ lib_LTLIBRARIES = libcppunit.la libcppunit_la_SOURCES = \ Asserter.cpp \ CompilerOutputter.cpp \ + Exception.cpp \ NotEqualException.cpp \ RepeatedTest.cpp \ SourceLine.cpp \ TestAssert.cpp \ TestCase.cpp \ - TestSuite.cpp \ - TestResult.cpp \ + TestFactoryRegistry.cpp \ TestFailure.cpp \ + TestResult.cpp \ TestRegistry.cpp \ - Exception.cpp \ + TestResultCollector.cpp \ + TestSucessListener.cpp \ + TestSuite.cpp \ + TextOutputter.cpp \ + TextTestProgressListener.cpp \ TextTestResult.cpp \ TextTestRunner.cpp \ - TestFactoryRegistry.cpp \ TypeInfoHelper.cpp \ XmlOutputter.cpp diff --git a/src/cppunit/Outputter.cpp b/src/cppunit/Outputter.cpp new file mode 100644 index 0000000..c011b1d --- /dev/null +++ b/src/cppunit/Outputter.cpp @@ -0,0 +1,21 @@ +#include <cppunit/Outputter.h> + + +namespace CppUnit +{ + + + + +Outputter::Outputter() +{ +} + + +Outputter::~Outputter() +{ +} + + +} // namespace CppUnit + diff --git a/src/cppunit/SynchronizedObject.cpp b/src/cppunit/SynchronizedObject.cpp new file mode 100644 index 0000000..c4e9c50 --- /dev/null +++ b/src/cppunit/SynchronizedObject.cpp @@ -0,0 +1,35 @@ +#include <cppunit/SynchronizedObject.h> + + +namespace CppUnit +{ + + + + +SynchronizedObject::SynchronizedObject( SynchronizationObject *syncObject ) + : m_syncObject( syncObject == 0 ? new SynchronizationObject() : + syncObject ) +{ +} + + +SynchronizedObject::~SynchronizedObject() +{ + delete m_syncObject; +} + + +/** Accept a new synchronization object for protection of this instance + * TestResult assumes ownership of the object + */ +void +SynchronizedObject::setSynchronizationObject( SynchronizationObject *syncObject ) +{ + delete m_syncObject; + m_syncObject = syncObject; +} + + +} // namespace CppUnit + diff --git a/src/cppunit/TestCase.cpp b/src/cppunit/TestCase.cpp index 9499416..8f5494a 100644 --- a/src/cppunit/TestCase.cpp +++ b/src/cppunit/TestCase.cpp @@ -10,124 +10,140 @@ namespace CppUnit { /// Create a default TestResult -CppUnit::TestResult* TestCase::defaultResult () -{ return new TestResult; } +CppUnit::TestResult* +TestCase::defaultResult() +{ + return new TestResult; +} /// Run the test and catch any exceptions that are triggered by it void -TestCase::run (TestResult *result) +TestCase::run( TestResult *result ) { - result->startTest (this); + result->startTest(this); - try { - setUp (); - - try { - runTest (); - } - catch (Exception& e) { + try { + setUp(); + + try { + runTest(); + } + catch ( Exception &e ) { Exception *copy = e.clone(); - result->addFailure (this, copy); - } - catch (std::exception& e) { - result->addError (this, new Exception (e.what ())); - } - catch (...) { - Exception *e = new Exception ("caught unknown exception"); - result->addError (this, e); - } - - try { - tearDown (); - } - catch ( ... ) { + result->addFailure( this, copy ); + } + catch ( std::exception &e ) { + result->addError( this, new Exception( e.what() ) ); + } + catch (...) { + Exception *e = new Exception( "caught unknown exception" ); + result->addError( this, e ); + } + + try { + tearDown(); + } + catch (...) { result->addError( this, new Exception( "tearDown() failed" ) ); - } - } - catch ( ... ) { - result->addError( this, new Exception( "setUp() failed" ) ); - } - - result->endTest (this); + } + } + catch (...) { + result->addError( this, new Exception( "setUp() failed" ) ); + } + + result->endTest( this ); } /// A default run method -TestResult *TestCase::run () +TestResult * +TestCase::run() { - TestResult *result = defaultResult (); + TestResult *result = defaultResult(); run (result); return result; - } + /// All the work for runTest is deferred to subclasses -void TestCase::runTest () +void +TestCase::runTest() { } + /** Constructs a test case. * \param name the name of the TestCase. **/ -TestCase::TestCase (std::string name) - : m_name (name) +TestCase::TestCase( std::string name ) + : m_name(name) { } + /** Constructs a test case for a suite. * This TestCase is intended for use by the TestCaller and should not * be used by a test case for which run() is called. **/ -TestCase::TestCase () - : m_name ("") +TestCase::TestCase() + : m_name( "" ) { } /// Destructs a test case -TestCase::~TestCase () -{} +TestCase::~TestCase() +{ +} /// Returns a count of all the tests executed -int TestCase::countTestCases () const -{ return 1; } +int +TestCase::countTestCases() const +{ + return 1; +} /// Returns the name of the test case std::string - TestCase::getName () const +TestCase::getName() const { return m_name; } /// A hook for fixture set up -void TestCase::setUp () -{} +void +TestCase::setUp() +{ +} /// A hook for fixture tear down -void TestCase::tearDown () -{} +void +TestCase::tearDown() +{ +} /// Returns the name of the test case instance std::string - TestCase::toString () const +TestCase::toString() const { std::string className; #if CPPUNIT_USE_TYPEINFO_NAME - const std::type_info& thisClass = typeid (*this); + const std::type_info& thisClass = typeid( *this ); className = thisClass.name(); #else className = "TestCase"; #endif - return className + "." + getName (); + return className + "." + getName(); } + } // namespace CppUnit diff --git a/src/cppunit/TestFailure.cpp b/src/cppunit/TestFailure.cpp index 51cd8cd..8404427 100644 --- a/src/cppunit/TestFailure.cpp +++ b/src/cppunit/TestFailure.cpp @@ -67,4 +67,11 @@ TestFailure::toString() const return m_failedTest->toString() + ": " + m_thrownException->what(); } + +TestFailure * +TestFailure::clone() const +{ + return new TestFailure( m_failedTest, m_thrownException->clone(), m_isError ); +} + } // namespace CppUnit diff --git a/src/cppunit/TestResult.cpp b/src/cppunit/TestResult.cpp index 784ab32..d5644a4 100644 --- a/src/cppunit/TestResult.cpp +++ b/src/cppunit/TestResult.cpp @@ -1,27 +1,21 @@ -#include "cppunit/TestResult.h" -#include "cppunit/TestListener.h" +#include <cppunit/TestFailure.h> +#include <cppunit/TestListener.h> +#include <cppunit/TestResult.h> #include <algorithm> namespace CppUnit { /// Construct a TestResult -TestResult::TestResult( SynchronizationObject *syncObject ) : - m_syncObject( syncObject == 0 ? new SynchronizationObject() : - syncObject ) +TestResult::TestResult( SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ) { - m_testErrors = 0; - m_stop = false; + reset(); } /// Destroys a test result TestResult::~TestResult() { - TestFailures::iterator itFailure = m_failures.begin(); - while ( itFailure != m_failures.end() ) - delete *itFailure++; - - delete m_syncObject; } @@ -33,9 +27,7 @@ void TestResult::reset() { ExclusiveZone zone( m_syncObject ); - m_testErrors = 0; - m_tests.clear(); - m_failures.clear(); + m_stop = false; } @@ -47,9 +39,7 @@ void TestResult::addError( Test *test, Exception *e ) { - ExclusiveZone zone( m_syncObject ); - ++m_testErrors; - addFailure( new TestFailure( test, e, true ) ); + addFailure( TestFailure( test, e, true ) ); } @@ -59,18 +49,16 @@ TestResult::addError( Test *test, void TestResult::addFailure( Test *test, Exception *e ) { - ExclusiveZone zone( m_syncObject ); - addFailure( new TestFailure( test, e, false ) ); + addFailure( TestFailure( test, e, false ) ); } /** Called to add a failure to the list of failures. */ void -TestResult::addFailure( TestFailure *failure ) +TestResult::addFailure( const TestFailure &failure ) { - m_failures.push_back( failure ); - + ExclusiveZone zone( m_syncObject ); for ( TestListeners::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it ) @@ -82,9 +70,7 @@ TestResult::addFailure( TestFailure *failure ) void TestResult::startTest( Test *test ) { - ExclusiveZone zone (m_syncObject); - m_tests.push_back( test ); - + ExclusiveZone zone( m_syncObject ); for ( TestListeners::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it ) @@ -96,8 +82,7 @@ TestResult::startTest( Test *test ) void TestResult::endTest( Test *test ) { - ExclusiveZone zone (m_syncObject); - + ExclusiveZone zone( m_syncObject ); for ( TestListeners::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it ) @@ -105,68 +90,6 @@ TestResult::endTest( Test *test ) } -/// Gets the number of run tests. -int -TestResult::runTests() const -{ - ExclusiveZone zone( m_syncObject ); - return m_tests.size(); -} - - -/// Gets the number of detected errors (uncaught exception). -int -TestResult::testErrors() const -{ - ExclusiveZone zone( m_syncObject ); - return m_testErrors; -} - - -/// Gets the number of detected failures (failed assertion). -int -TestResult::testFailures() const -{ - ExclusiveZone zone( m_syncObject ); - return m_failures.size() - m_testErrors; -} - - -/// Gets the total number of detected failures. -int -TestResult::testFailuresTotal() const -{ - ExclusiveZone zone( m_syncObject ); - return m_failures.size(); -} - - -/// Returns whether the entire test was successful or not. -bool -TestResult::wasSuccessful() const -{ - ExclusiveZone zone( m_syncObject ); - return m_failures.size() == 0; -} - - -/// Returns a the list failures (random access collection). -const TestResult::TestFailures & -TestResult::failures() const -{ - ExclusiveZone zone( m_syncObject ); - return m_failures; -} - - -const TestResult::Tests & -TestResult::tests() const -{ - ExclusiveZone zone( m_syncObject ); - return m_tests; -} - - /// Returns whether testing should be stopped bool TestResult::shouldStop() const @@ -185,21 +108,10 @@ TestResult::stop() } -/** Accept a new synchronization object for protection of this instance - * TestResult assumes ownership of the object - */ -void -TestResult::setSynchronizationObject( SynchronizationObject *syncObject ) -{ - delete m_syncObject; - m_syncObject = syncObject; -} - - void TestResult::addListener( TestListener *listener ) { - ExclusiveZone zone (m_syncObject); + ExclusiveZone zone( m_syncObject ); m_listeners.push_back( listener ); } @@ -207,7 +119,7 @@ TestResult::addListener( TestListener *listener ) void TestResult::removeListener ( TestListener *listener ) { - ExclusiveZone zone (m_syncObject); + ExclusiveZone zone( m_syncObject ); m_listeners.erase( std::remove( m_listeners.begin(), m_listeners.end(), listener ), diff --git a/src/cppunit/TestResultCollector.cpp b/src/cppunit/TestResultCollector.cpp new file mode 100644 index 0000000..796ffc3 --- /dev/null +++ b/src/cppunit/TestResultCollector.cpp @@ -0,0 +1,110 @@ +#include <cppunit/TestFailure.h> +#include <cppunit/TestResultCollector.h> + + +namespace CppUnit +{ + + +TestResultCollector::TestResultCollector( SynchronizationObject *syncObject ) + : TestSucessListener( syncObject ) +{ + reset(); +} + + +TestResultCollector::~TestResultCollector() +{ + TestFailures::iterator itFailure = m_failures.begin(); + while ( itFailure != m_failures.end() ) + delete *itFailure++; +} + + +void +TestResultCollector::reset() +{ + TestSucessListener::reset(); + + ExclusiveZone zone( m_syncObject ); + m_testErrors = 0; + m_tests.clear(); + m_failures.clear(); +} + + +void +TestResultCollector::startTest( Test *test ) +{ + ExclusiveZone zone (m_syncObject); + m_tests.push_back( test ); +} + + +void +TestResultCollector::addFailure( const TestFailure &failure ) +{ + TestSucessListener::addFailure( failure ); + + ExclusiveZone zone( m_syncObject ); + if ( failure.isError() ) + ++m_testErrors; + m_failures.push_back( failure.clone() ); +} + + +/// Gets the number of run tests. +int +TestResultCollector::runTests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests.size(); +} + + +/// Gets the number of detected errors (uncaught exception). +int +TestResultCollector::testErrors() const +{ + ExclusiveZone zone( m_syncObject ); + return m_testErrors; +} + + +/// Gets the number of detected failures (failed assertion). +int +TestResultCollector::testFailures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size() - m_testErrors; +} + + +/// Gets the total number of detected failures. +int +TestResultCollector::testFailuresTotal() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size(); +} + + +/// Returns a the list failures (random access collection). +const TestResultCollector::TestFailures & +TestResultCollector::failures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures; +} + + +const TestResultCollector::Tests & +TestResultCollector::tests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests; +} + + +} // namespace CppUnit + diff --git a/src/cppunit/TestSucessListener.cpp b/src/cppunit/TestSucessListener.cpp new file mode 100644 index 0000000..7271c6b --- /dev/null +++ b/src/cppunit/TestSucessListener.cpp @@ -0,0 +1,46 @@ +#include <cppunit/TestSucessListener.h> + + + +namespace CppUnit +{ + + +TestSucessListener::TestSucessListener( SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ) + , m_sucess( true ) +{ +} + + +TestSucessListener::~TestSucessListener() +{ +} + + +void +TestSucessListener::reset() +{ + ExclusiveZone zone( m_syncObject ); + m_sucess = true; +} + + +void +TestSucessListener::addFailure( const TestFailure &failure ) +{ + ExclusiveZone zone( m_syncObject ); + m_sucess = false; +} + + +bool +TestSucessListener::wasSuccessful() const +{ + ExclusiveZone zone( m_syncObject ); + return m_sucess; +} + + +} // namespace CppUnit + diff --git a/src/cppunit/TextOutputter.cpp b/src/cppunit/TextOutputter.cpp new file mode 100644 index 0000000..fc32598 --- /dev/null +++ b/src/cppunit/TextOutputter.cpp @@ -0,0 +1,156 @@ +#include <cppunit/NotEqualException.h> +#include <cppunit/TestFailure.h> +#include <cppunit/SourceLine.h> +#include <cppunit/TestResultCollector.h> +#include <cppunit/TextOutputter.h> + + +namespace CppUnit +{ + + +TextOutputter::TextOutputter( TestResultCollector *result, + std::ostream &stream ) + : m_result( result ) + , m_stream( stream ) +{ +} + + +TextOutputter::~TextOutputter() +{ +} + + +void +TextOutputter::write() +{ + printHeader(); + m_stream << std::endl; + printFailures(); + m_stream << std::endl; +} + + +void +TextOutputter::printFailures() +{ + TestResultCollector::TestFailures::const_iterator itFailure = m_result->failures().begin(); + int failureNumber = 1; + while ( itFailure != m_result->failures().end() ) + { + m_stream << std::endl; + printFailure( *itFailure++, failureNumber++ ); + } +} + + +void +TextOutputter::printFailure( TestFailure *failure, + int failureNumber ) +{ + printFailureListMark( failureNumber ); + m_stream << ' '; + printFailureTestName( failure ); + m_stream << ' '; + printFailureType( failure ); + m_stream << ' '; + printFailureLocation( failure->sourceLine() ); + m_stream << std::endl; + printFailureDetail( failure->thrownException() ); + m_stream << std::endl; +} + + +void +TextOutputter::printFailureListMark( int failureNumber ) +{ + m_stream << failureNumber << ")"; +} + + +void +TextOutputter::printFailureTestName( TestFailure *failure ) +{ + m_stream << "test: " << failure->failedTestName(); +} + + +void +TextOutputter::printFailureType( TestFailure *failure ) +{ + m_stream << "(" + << (failure->isError() ? "E" : "F") + << ")"; +} + + +void +TextOutputter::printFailureLocation( SourceLine sourceLine ) +{ + if ( !sourceLine.isValid() ) + return; + + m_stream << "line: " << sourceLine.lineNumber() + << ' ' << sourceLine.fileName(); +} + + +void +TextOutputter::printFailureDetail( Exception *thrownException ) +{ + if ( thrownException->isInstanceOf( NotEqualException::type() ) ) + { + NotEqualException *e = (NotEqualException*)thrownException; + m_stream << "expected: " << e->expectedValue() << std::endl + << "but was: " << e->actualValue(); + if ( !e->additionalMessage().empty() ) + { + m_stream << std::endl; + m_stream << "additional message:" << std::endl + << e->additionalMessage(); + } + } + else + { + m_stream << " \"" << thrownException->what() << "\""; + } +} + + +void +TextOutputter::printHeader() +{ + if ( m_result->wasSuccessful() ) + m_stream << std::endl << "OK (" << m_result->runTests () << " tests)" + << std::endl; + else + { + m_stream << std::endl; + printFailureWarning(); + printStatistics(); + } +} + + +void +TextOutputter::printFailureWarning() +{ + m_stream << "!!!FAILURES!!!" << std::endl; +} + + +void +TextOutputter::printStatistics() +{ + m_stream << "Test Results:" << std::endl; + + m_stream << "Run: " << m_result->runTests() + << " Failures: " << m_result->testFailures() + << " Errors: " << m_result->testErrors() + << std::endl; +} + + +} // namespace CppUnit + diff --git a/src/cppunit/TextTestProgressListener.cpp b/src/cppunit/TextTestProgressListener.cpp new file mode 100644 index 0000000..815c04c --- /dev/null +++ b/src/cppunit/TextTestProgressListener.cpp @@ -0,0 +1,41 @@ +#include <cppunit/TestFailure.h> +#include <cppunit/TextTestProgressListener.h> +#include <iostream> + + +namespace CppUnit +{ + + +TextTestProgressListener::TextTestProgressListener() +{ +} + + +TextTestProgressListener::~TextTestProgressListener() +{ +} + + +void +TextTestProgressListener::startTest( Test *test ) +{ + std::cerr << "."; +} + + +void +TextTestProgressListener::addFailure( const TestFailure &failure ) +{ + std::cerr << ( failure.isError() ? "E" : "F" ); +} + + +void +TextTestProgressListener::done() +{ + std::cerr << std::endl; +} + +} // namespace CppUnit + diff --git a/src/cppunit/TextTestResult.cpp b/src/cppunit/TextTestResult.cpp index 44a8fa6..a8483b7 100644 --- a/src/cppunit/TextTestResult.cpp +++ b/src/cppunit/TextTestResult.cpp @@ -1,6 +1,7 @@ #include <cppunit/Exception.h> #include <cppunit/NotEqualException.h> #include <cppunit/Test.h> +#include <cppunit/TestFailure.h> #include <cppunit/TextTestResult.h> #include <iostream> @@ -8,28 +9,24 @@ namespace CppUnit { -void -TextTestResult::addError( Test *test, - Exception *e ) +TextTestResult::TextTestResult() { - TestResult::addError( test, e ); - std::cerr << "E"; + addListener( this ); } void -TextTestResult::addFailure( Test *test, - Exception *e ) +TextTestResult::addFailure( const TestFailure &failure ) { - TestResult::addFailure (test, e); - std::cerr << "F"; + TestResultCollector::addFailure( failure ); + std::cerr << ( failure.isError() ? "E" : "F" ); } void TextTestResult::startTest( Test *test ) { - TestResult::startTest (test); + TestResultCollector::startTest (test); std::cerr << "."; } diff --git a/src/cppunit/TextTestRunner.cpp b/src/cppunit/TextTestRunner.cpp index 8b4da15..8767427 100644 --- a/src/cppunit/TextTestRunner.cpp +++ b/src/cppunit/TextTestRunner.cpp @@ -1,8 +1,10 @@ - #include <iostream> #include <cppunit/TestSuite.h> #include <cppunit/TextTestRunner.h> #include <cppunit/TextTestResult.h> +#include <cppunit/TextOutputter.h> +#include <cppunit/TextTestProgressListener.h> +#include <cppunit/TestResult.h> namespace CppUnit { @@ -16,16 +18,22 @@ namespace CppUnit { * is specified then a default TextTestResult is * instanciated. */ -TextTestRunner::TextTestRunner( TextTestResult *result ) : - m_result( result == 0 ? new TextTestResult() : - result ), - m_suite( new TestSuite( "All Tests" ) ) +TextTestRunner::TextTestRunner( Outputter *outputter ) + : m_outputter( outputter ) + , m_suite( new TestSuite( "All Tests" ) ) + , m_result( new TestResultCollector() ) + , m_eventManager( new TestResult() ) { + if ( !m_outputter ) + m_outputter = new TextOutputter( m_result, std::cout ); + m_eventManager->addListener( m_result ); } TextTestRunner::~TextTestRunner() { + delete m_eventManager; + delete m_outputter; delete m_result; delete m_suite; } @@ -98,7 +106,7 @@ TextTestRunner::printResult( bool doPrintResult ) { std::cout << std::endl; if ( doPrintResult ) - std::cout << *m_result << std::endl; + m_outputter->write(); } @@ -120,15 +128,33 @@ TextTestRunner::findTestByName( std::string name ) const bool TextTestRunner::runTest( Test *test ) { - test->run( m_result ); + TextTestProgressListener progress; + m_eventManager->addListener( &progress ); + test->run( m_eventManager ); + m_eventManager->removeListener( &progress ); return m_result->wasSuccessful(); } -TextTestResult * -TextTestRunner::result() +TestResultCollector & +TextTestRunner::result() const +{ + return *m_result; +} + + +TestResult & +TextTestRunner::eventManager() const +{ + return *m_eventManager; +} + + +void +TextTestRunner::setOutputter( Outputter *outputter ) { - return m_result; + delete m_outputter; + m_outputter = outputter; } diff --git a/src/cppunit/XmlOutputter.cpp b/src/cppunit/XmlOutputter.cpp index 93cf88f..540482d 100644 --- a/src/cppunit/XmlOutputter.cpp +++ b/src/cppunit/XmlOutputter.cpp @@ -1,6 +1,7 @@ #include <cppunit/Exception.h> #include <cppunit/Test.h> -#include <cppunit/TestResult.h> +#include <cppunit/TestFailure.h> +#include <cppunit/TestResultCollector.h> #include <cppunit/XmlOutputter.h> #include <map> #include <stdlib.h> @@ -150,8 +151,8 @@ XmlOutputter::Node::asString( int value ) // XmlOutputter // ////////////////////////////////////////////////////////////////// -XmlOutputter::XmlOutputter( TestResult *result, - std::ostream &stream ) : +XmlOutputter::XmlOutputter( TestResultCollector *result, + std::ostream &stream ) : m_result( result ), m_stream( stream ) { @@ -208,8 +209,8 @@ XmlOutputter::makeRootNode() void XmlOutputter::fillFailedTestsMap( FailedTests &failedTests ) { - const TestResult::TestFailures &failures = m_result->failures(); - TestResult::TestFailures::const_iterator itFailure = failures.begin(); + const TestResultCollector::TestFailures &failures = m_result->failures(); + TestResultCollector::TestFailures::const_iterator itFailure = failures.begin(); while ( itFailure != failures.end() ) { TestFailure *failure = *itFailure++; @@ -225,7 +226,7 @@ XmlOutputter::addFailedTests( FailedTests &failedTests, Node *testsNode = new Node( "FailedTests" ); rootNode->addNode( testsNode ); - const TestResult::Tests &tests = m_result->tests(); + const TestResultCollector::Tests &tests = m_result->tests(); for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) { Test *test = tests[testNumber]; @@ -242,7 +243,7 @@ XmlOutputter::addSucessfulTests( FailedTests &failedTests, Node *testsNode = new Node( "SucessfulTests" ); rootNode->addNode( testsNode ); - const TestResult::Tests &tests = m_result->tests(); + const TestResultCollector::Tests &tests = m_result->tests(); for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) { Test *test = tests[testNumber]; diff --git a/src/cppunit/cppunit.dsp b/src/cppunit/cppunit.dsp index df7c41d..e1120e1 100644 --- a/src/cppunit/cppunit.dsp +++ b/src/cppunit/cppunit.dsp @@ -210,6 +210,14 @@ SOURCE=..\..\include\cppunit\SourceLine.h # End Source File # Begin Source File +SOURCE=.\SynchronizedObject.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\SynchronizedObject.h +# End Source File +# Begin Source File + SOURCE=..\..\include\cppunit\Test.h # End Source File # Begin Source File @@ -271,6 +279,42 @@ SOURCE=..\..\include\cppunit\CompilerOutputter.h # End Source File # Begin Source File +SOURCE=..\..\include\cppunit\Outputter.h +# End Source File +# Begin Source File + +SOURCE=.\TestResultCollector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestResultCollector.h +# End Source File +# Begin Source File + +SOURCE=.\TestSucessListener.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestSucessListener.h +# End Source File +# Begin Source File + +SOURCE=.\TextOutputter.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TextOutputter.h +# End Source File +# Begin Source File + +SOURCE=.\TextTestProgressListener.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TextTestProgressListener.h +# End Source File +# Begin Source File + SOURCE=.\TextTestResult.cpp # End Source File # Begin Source File diff --git a/src/msvc6/testrunner/GUITestResult.cpp b/src/msvc6/testrunner/GUITestResult.cpp deleted file mode 100644 index d1b300c..0000000 --- a/src/msvc6/testrunner/GUITestResult.cpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include "stdafx.h" -#include "TestRunnerDlg.h" -#include "GUITestResult.h" - - -void GUITestResult::addError (CppUnit::Test *test, CppUnit::Exception *e) -{ - ExclusiveZone zone (m_syncObject); - - TestResult::addError (test, e); - m_runner->addError (this, test, e); -} - -void GUITestResult::addFailure (CppUnit::Test *test, CppUnit::Exception *e) -{ - ExclusiveZone zone (m_syncObject); - - TestResult::addFailure (test, e); - m_runner->addFailure (this, test, e); -} - -void GUITestResult::endTest (CppUnit::Test *test) -{ - ExclusiveZone zone (m_syncObject); - - TestResult::endTest (test); - m_runner->endTest (this, test); -} - diff --git a/src/msvc6/testrunner/GUITestResult.h b/src/msvc6/testrunner/GUITestResult.h deleted file mode 100644 index e0a7c11..0000000 --- a/src/msvc6/testrunner/GUITestResult.h +++ /dev/null @@ -1,59 +0,0 @@ - - -#ifndef CPPUNIT_GUITESTRESULT_H -#define CPPUNIT_GUITESTRESULT_H - -#include <afxmt.h> - -#ifndef TESTRESULT_H -#include <cppunit/TestResult.h> -#endif - -class TestRunnerDlg; - - - -class GUITestResult : public CppUnit::TestResult -{ -public: - GUITestResult (TestRunnerDlg *runner); - ~GUITestResult (); - - void addError (CppUnit::Test *test, CppUnit::Exception *e); - void addFailure (CppUnit::Test *test, CppUnit::Exception *e); - - void endTest (CppUnit::Test *test); - void stop (); - -protected: - class LightweightSynchronizationObject : public TestResult::SynchronizationObject - { - CCriticalSection m_syncObject; - - public: - void lock () { m_syncObject.Lock (); } - void unlock () { m_syncObject.Unlock (); } - }; - -private: - TestRunnerDlg *m_runner; -}; - - - -// Construct with lightweight synchronization -inline GUITestResult::GUITestResult (TestRunnerDlg *runner) -: m_runner (runner) { setSynchronizationObject (new LightweightSynchronizationObject ()); } - - -// Destructor -inline GUITestResult::~GUITestResult () -{} - - -// Override without protection to prevent deadlock -inline void GUITestResult::stop () -{ m_stop = true; } - - -#endif diff --git a/src/msvc6/testrunner/MfcSynchronizationObject.h b/src/msvc6/testrunner/MfcSynchronizationObject.h new file mode 100644 index 0000000..2b68712 --- /dev/null +++ b/src/msvc6/testrunner/MfcSynchronizationObject.h @@ -0,0 +1,39 @@ +// ////////////////////////////////////////////////////////////////////////// +// Header file LightweightSynchronizationObject.h for class LightweightSynchronizationObject +// (c)Copyright 2000, Baptiste Lepilleur. +// Created: 2002/02/27 +// ////////////////////////////////////////////////////////////////////////// +#ifndef LIGHTWEIGHTSYNCHRONIZATIONOBJECT_H +#define LIGHTWEIGHTSYNCHRONIZATIONOBJECT_H + +#include <cppunit/SynchronizedObject.h> + + +/*! \class LightweightSynchronizationObject + * \brief This class represents a lock object for synchronized object. + */ +class MfcSynchronizationObject + : public CppUnit::SynchronizedObject::SynchronizationObject +{ + CCriticalSection m_syncObject; + +public: + void lock() + { + m_syncObject.Lock(); + } + + void unlock() + { + m_syncObject.Unlock(); + } +}; + + + +// Inlines methods for LightweightSynchronizationObject: +// ----------------------------------------------------- + + + +#endif // LIGHTWEIGHTSYNCHRONIZATIONOBJECT_H diff --git a/src/msvc6/testrunner/TestRunner.dsp b/src/msvc6/testrunner/TestRunner.dsp index 6a9d486..37ee1a7 100644 --- a/src/msvc6/testrunner/TestRunner.dsp +++ b/src/msvc6/testrunner/TestRunner.dsp @@ -247,11 +247,7 @@ SOURCE=.\ActiveTest.h # End Source File # Begin Source File -SOURCE=.\GUITestResult.cpp -# End Source File -# Begin Source File - -SOURCE=.\GUITestResult.h +SOURCE=.\MfcSynchronizationObject.h # End Source File # Begin Source File diff --git a/src/msvc6/testrunner/TestRunner.rc b/src/msvc6/testrunner/TestRunner.rc index 69a3c34..3c21114 100644 --- a/src/msvc6/testrunner/TestRunner.rc +++ b/src/msvc6/testrunner/TestRunner.rc @@ -129,7 +129,7 @@ BEGIN COMBOBOX IDC_COMBO_TEST,7,17,332,157,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "&Autorun at startup",IDC_CHECK_AUTORUN,"Button", - BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,348,67,49,25 + BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,348,73,49,19 PUSHBUTTON "&Stop",ID_STOP,347,177,50,14 PUSHBUTTON "&Close",IDOK,347,193,50,14 LTEXT "Progress:",IDC_STATIC,7,38,49,9 diff --git a/src/msvc6/testrunner/TestRunnerDlg.cpp b/src/msvc6/testrunner/TestRunnerDlg.cpp index 68a1cc5..b7bcfb8 100644 --- a/src/msvc6/testrunner/TestRunnerDlg.cpp +++ b/src/msvc6/testrunner/TestRunnerDlg.cpp @@ -7,11 +7,12 @@ #include "TestRunnerDlg.h" #include "Resource.h" #include "ActiveTest.h" -#include "GUITestResult.h" #include "ProgressBar.h" #include "TreeHierarchyDlg.h" #include "ListCtrlFormatter.h" #include "ListCtrlSetter.h" +#include "MfcSynchronizationObject.h" +#include <cppunit/TestFailure.h> #ifdef _DEBUG #define new DEBUG_NEW @@ -21,6 +22,9 @@ static char THIS_FILE[] = __FILE__; /* Notes: - code duplication between OnOK() and OnQuitApplication() + - the threading need to be rewrite, so that GUI update occures in the original + thread, not in the thread that is running the tests. This slow down the time + needed to run the test much... */ @@ -106,6 +110,7 @@ TestRunnerDlg::OnInitDialog() loadSettings(); listCtrl->SetImageList( &m_errorListBitmap, LVSIL_SMALL ); + listCtrl->SetExtendedStyle( listCtrl->GetExtendedStyle() | LVS_EX_FULLROWSELECT ); int total_col_1_4 = m_settings.col_1 + m_settings.col_2 + m_settings.col_3 + m_settings.col_4; @@ -133,13 +138,6 @@ TestRunnerDlg::OnInitDialog() if ( r.right-r.left > 0 && r.bottom-r.top > 0 ) MoveWindow( &r ); - // somehow doesn't have the desired effect? - LONG extendedStyle = GetWindowLong( m_listCtrl.GetSafeHwnd(), - GWL_EXSTYLE);; - SetWindowLong( m_listCtrl.GetSafeHwnd(), - GWL_EXSTYLE, - extendedStyle | LVS_EX_FULLROWSELECT); - m_buttonRun.SetFocus(); if ( m_bAutorunAtStartup ) @@ -177,57 +175,58 @@ TestRunnerDlg::OnRun() m_testsProgress->start( numberOfTests ); - m_result = new GUITestResult( (TestRunnerDlg *)this ); + + m_result = new CppUnit::TestResultCollector( new MfcSynchronizationObject() ); + m_testObserver = new CppUnit::TestResult( new MfcSynchronizationObject() ); + m_testObserver->addListener( m_result ); + m_testObserver->addListener( this ); m_activeTest = new ActiveTest( m_selectedTest ); m_testStartTime = timeGetTime(); - m_activeTest->run( m_result ); + m_activeTest->run( m_testObserver ); m_testEndTime = timeGetTime(); } void -TestRunnerDlg::addListEntry( std::string type, - CppUnit::TestResult *result, - CppUnit::Test *test, - CppUnit::Exception *e ) +TestRunnerDlg::addListEntry( const CppUnit::TestFailure &failure ) { CListCtrl *listCtrl = (CListCtrl *)GetDlgItem (IDC_LIST); - int currentEntry = result->testErrors() + - result->testFailures() -1; + int currentEntry = m_result->testErrors() + + m_result->testFailures() -1; ErrorTypeBitmaps errorType; - if ( type == "Failure" ) - errorType = errorTypeFailure; - else + if ( failure.isError() ) errorType = errorTypeError; + else + errorType = errorTypeFailure; ListCtrlSetter setter( *listCtrl ); setter.insertLine( currentEntry ); - setter.addSubItem( errorType, type ); + setter.addSubItem( errorType, failure.isError() ? "Error" : "Failure" ); // Set test name - setter.addSubItem( errorType, test->getName() ); + setter.addSubItem( errorType, failure.failedTestName() ); // Set the asserted text - setter.addSubItem( e->what() ); + setter.addSubItem( failure.thrownException()->what() ); // Set the line number - if (e->sourceLine().isValid() ) + if ( failure.sourceLine().isValid() ) { char tmp[64]; - sprintf( tmp, "%ld", e->sourceLine().lineNumber() ); + sprintf( tmp, "%ld", failure.sourceLine().lineNumber() ); setter.addSubItem( tmp ); } else setter.addSubItem( "" ); // Set the file name - setter.addSubItem( e->sourceLine().fileName() ); + setter.addSubItem( failure.sourceLine().fileName() ); -/* In place of the missing detail fiedl... +/* In place of the missing detail field... std::string dump = "Test: " + test->getName() + "\n"; dump += e->what(); dump += "\n"; @@ -240,28 +239,26 @@ TestRunnerDlg::addListEntry( std::string type, void -TestRunnerDlg::addError (CppUnit::TestResult *result, CppUnit::Test *test, CppUnit::Exception *e) +TestRunnerDlg::startTest( CppUnit::Test *test ) { - addListEntry ("Error", result, test, e); - m_errors++; - - updateCountsDisplay (); } void -TestRunnerDlg::addFailure (CppUnit::TestResult *result, CppUnit::Test *test, CppUnit::Exception *e) +TestRunnerDlg::addFailure( const CppUnit::TestFailure &failure ) { - addListEntry ("Failure", result, test, e); - m_failures++; + addListEntry( failure ); + if ( failure.isError() ) + m_errors++; + else + m_failures++; - updateCountsDisplay (); + updateCountsDisplay(); } void -TestRunnerDlg::endTest( CppUnit::TestResult *result, - CppUnit::Test *test ) +TestRunnerDlg::endTest( CppUnit::Test *test ) { if ( m_selectedTest == 0 ) return; @@ -321,30 +318,33 @@ TestRunnerDlg::freeState() { delete m_activeTest; delete m_result; + delete m_testObserver; } void TestRunnerDlg::reset() { - m_testsRun = 0; - m_errors = 0; - m_failures = 0; - m_testEndTime = m_testStartTime; + m_testsRun = 0; + m_errors = 0; + m_failures = 0; + m_testEndTime = m_testStartTime; - updateCountsDisplay (); + updateCountsDisplay(); - m_activeTest = 0; - m_result = 0; + m_activeTest = NULL; + m_result = NULL; + m_testObserver = NULL; CListCtrl *listCtrl = (CListCtrl *)GetDlgItem (IDC_LIST); - listCtrl->DeleteAllItems (); - m_testsProgress->reset (); + listCtrl->DeleteAllItems(); + m_testsProgress->reset(); } -void TestRunnerDlg::updateCountsDisplay () +void +TestRunnerDlg::updateCountsDisplay() { CStatic *statTestsRun = (CStatic *)GetDlgItem (IDC_STATIC_RUNS); CStatic *statErrors = (CStatic *)GetDlgItem (IDC_STATIC_ERRORS); @@ -370,8 +370,8 @@ void TestRunnerDlg::updateCountsDisplay () void TestRunnerDlg::OnStop() { - if (m_result) - m_result->stop (); + if ( m_testObserver ) + m_testObserver->stop (); beIdle (); } @@ -380,8 +380,8 @@ TestRunnerDlg::OnStop() void TestRunnerDlg::OnOK() { - if (m_result) - m_result->stop (); + if ( m_testObserver ) + m_testObserver->stop (); UpdateData(); saveSettings(); @@ -507,8 +507,8 @@ TestRunnerDlg::saveSettings() void TestRunnerDlg::OnQuitApplication() { - if (m_result) - m_result->stop (); + if ( m_testObserver ) + m_testObserver->stop(); UpdateData(); saveSettings(); @@ -537,27 +537,14 @@ TestRunnerDlg::OnClose() void TestRunnerDlg::updateLayoutInfo() { - RECT r; - RECT dlgBounds; - // get dialog in screen co-ordinates + RECT dlgBounds; GetWindowRect( &dlgBounds ); // Set general margin according to distance of browse button from the right - CWnd * pItem = GetDlgItem(IDC_BROWSE_TEST); - pItem->GetWindowRect( &r ); - - m_margin = dlgBounds.right - r.right; - - pItem = GetDlgItem(IDC_LIST); - pItem->GetWindowRect( &r ); - - m_listViewDelta = dlgBounds.bottom - r.bottom; - - pItem = GetDlgItem(IDC_EDIT_TIME); - pItem->GetWindowRect( &r ); - - m_editDelta = dlgBounds.bottom - r.bottom; + m_margin = dlgBounds.right - getItemWindowRect(IDC_BROWSE_TEST).right; + m_listViewDelta = dlgBounds.bottom - getItemWindowRect( IDC_LIST ).bottom; + m_editDelta = dlgBounds.bottom - getItemWindowRect( IDC_EDIT_TIME ).bottom; } @@ -568,9 +555,7 @@ TestRunnerDlg::OnSize(UINT nType, int cx, int cy) // Layout controls according to new size CRect r; - CRect dlgBounds; - GetClientRect(&dlgBounds); - ClientToScreen(&dlgBounds); + CRect dlgBounds = getDialogBounds(); int buttonLeft = 0; int buttonRight = 0; @@ -591,76 +576,11 @@ TestRunnerDlg::OnSize(UINT nType, int cx, int cy) pItem->MoveWindow( &r ); pItem->Invalidate(); } - - pItem = GetDlgItem(ID_RUN); - if (pItem) - { - pItem->GetClientRect( &r ); - pItem->ClientToScreen( &r ); - - // adjust to dialog units - r.OffsetRect(-dlgBounds.left, -dlgBounds.top); - r.left = buttonLeft; - r.right = buttonRight; - - pItem->MoveWindow( &r ); - pItem->Invalidate(); - } - - pItem = GetDlgItem(IDC_CHECK_AUTORUN); - if (pItem) - { - pItem->GetClientRect( &r ); - pItem->ClientToScreen( &r ); - - // adjust to dialog units - r.OffsetRect(-dlgBounds.left, -dlgBounds.top); - r.left = buttonLeft; - r.right = buttonRight; - - pItem->MoveWindow( &r ); - pItem->Invalidate(); - } - - pItem = GetDlgItem(IDOK); // Close button - if (pItem) - { - pItem->GetClientRect( &r ); - pItem->ClientToScreen( &r ); - - // adjust to dialog units - r.OffsetRect(-dlgBounds.left, -dlgBounds.top); - r.left = buttonLeft; - r.right = buttonRight; - - int height = r.Height(); - // order matters here ( r.top uses new r.bottom ) - r.bottom = cy - m_editDelta; - r.top = r.bottom - height; - - pItem->MoveWindow( &r ); - pItem->Invalidate(); - } - - pItem = GetDlgItem(ID_STOP); - if (pItem) - { - pItem->GetClientRect( &r ); - pItem->ClientToScreen( &r ); - - // adjust to dialog units - r.OffsetRect(-dlgBounds.left, -dlgBounds.top); - r.left = buttonLeft; - r.right = buttonRight; - - int height = r.Height(); - // order matters here ( r.top uses new r.bottom ) - r.bottom = cy - m_listViewDelta; - r.top = r.bottom - height; - - pItem->MoveWindow( &r ); - pItem->Invalidate(); - } + + updateTopButtonPosition( ID_RUN, buttonLeft, buttonRight ); + updateTopButtonPosition( IDC_CHECK_AUTORUN, buttonLeft, buttonRight ); + updateBottomButtonPosition( IDOK, buttonLeft, buttonRight, cy - m_editDelta ); + updateBottomButtonPosition( ID_STOP, buttonLeft, buttonRight, cy - m_listViewDelta ); pItem = GetDlgItem(IDC_COMBO_TEST); if (pItem) @@ -675,37 +595,8 @@ TestRunnerDlg::OnSize(UINT nType, int cx, int cy) pItem->MoveWindow( &r ); pItem->Invalidate(); } - - pItem = GetDlgItem(IDC_LIST); - if (pItem) - { - pItem->GetWindowRect( &r ); - - // adjust to dialog units - r.OffsetRect(-dlgBounds.left, -dlgBounds.top); - - r.right = buttonLeft - m_margin; - - // resize to fit last column - - LVCOLUMN lv; - lv.mask = LVCF_WIDTH; - int width_1_4 = 0; - for (int i = 0; i < 4; ++i) - { - m_listCtrl.GetColumn(i, &lv); - width_1_4 += lv.cx; - } - - // the 4 offset is so no horiz scroll bar will appear - m_listCtrl.SetColumnWidth(4, r.Width() - width_1_4 - 4); - - // order matters here ( r.top uses new r.bottom ) - r.bottom = cy - m_listViewDelta; - - pItem->MoveWindow( &r ); - pItem->Invalidate(); - } + + updateListPosition( buttonLeft ); if (m_testsProgress) { @@ -732,3 +623,114 @@ TestRunnerDlg::OnSize(UINT nType, int cx, int cy) } } + +void +TestRunnerDlg::updateTopButtonPosition( unsigned int buttonId, + int xButtonLeft, + int xButtonRight ) +{ + CWnd *pItem = GetDlgItem( buttonId ); + if ( !pItem ) + return; + + CRect r; + pItem->GetClientRect( &r ); + pItem->ClientToScreen( &r ); + + // adjust to dialog units + CRect dlgBounds = getDialogBounds(); + r.OffsetRect( -dlgBounds.left, -dlgBounds.top ); + r.left = xButtonLeft; + r.right = xButtonRight; + + pItem->MoveWindow( &r ); + pItem->Invalidate(); +} + + +void +TestRunnerDlg::updateBottomButtonPosition( unsigned int buttonId, + int xButtonLeft, + int xButtonRight, + int yButtonBottom ) +{ + CWnd *pItem = GetDlgItem( buttonId ); + if ( !pItem ) + return; + + CRect r; + pItem->GetClientRect( &r ); + pItem->ClientToScreen( &r ); + + // adjust to dialog units + CRect dlgBounds = getDialogBounds(); + r.OffsetRect(-dlgBounds.left, -dlgBounds.top); + r.left = xButtonLeft; + r.right = xButtonRight; + + int height = r.Height(); + // order matters here ( r.top uses new r.bottom ) + r.bottom = yButtonBottom; + r.top = r.bottom - height; + + pItem->MoveWindow( &r ); + pItem->Invalidate(); +} + + +void +TestRunnerDlg::updateListPosition( int xButtonLeft ) +{ + CWnd *pItem = GetDlgItem( IDC_LIST ); + if ( !pItem ) + return; + CRect r; + pItem->GetWindowRect( &r ); + + // adjust to dialog units + CRect dlgBounds = getDialogBounds(); + r.OffsetRect(-dlgBounds.left, -dlgBounds.top); + + r.right = xButtonLeft - m_margin; + + // resize to fit last column + + LVCOLUMN lv; + lv.mask = LVCF_WIDTH; + int width_1_4 = 0; + for (int i = 0; i < 4; ++i) + { + m_listCtrl.GetColumn(i, &lv); + width_1_4 += lv.cx; + } + + // the 4 offset is so no horiz scroll bar will appear + m_listCtrl.SetColumnWidth(4, r.Width() - width_1_4 - 4); + + // order matters here ( r.top uses new r.bottom ) + r.bottom = getDialogBounds().Height() - m_listViewDelta; + + pItem->MoveWindow( &r ); + pItem->Invalidate(); +} + + +CRect +TestRunnerDlg::getItemWindowRect( unsigned int itemId ) +{ + CWnd * pItem = GetDlgItem( itemId ); + CRect rect; + if ( pItem ) + pItem->GetWindowRect( &rect ); + return rect; +} + + +CRect +TestRunnerDlg::getDialogBounds() +{ + CRect dlgBounds; + GetClientRect( &dlgBounds ); + ClientToScreen( &dlgBounds ); + return dlgBounds; +} diff --git a/src/msvc6/testrunner/TestRunnerDlg.h b/src/msvc6/testrunner/TestRunnerDlg.h index 730487f..ca600cc 100644 --- a/src/msvc6/testrunner/TestRunnerDlg.h +++ b/src/msvc6/testrunner/TestRunnerDlg.h @@ -30,6 +30,9 @@ #include <vector> #include <cppunit/TestSuite.h> #include <cppunit/Exception.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestListener.h> +#include <cppunit/TestResultCollector.h> #include "ActiveTest.h" #include "MsDevCallerListCtrl.h" @@ -42,7 +45,8 @@ class TestRunnerModel; ///////////////////////////////////////////////////////////////////////////// // TestRunnerDlg dialog -class AFX_EXT_CLASS TestRunnerDlg : public CDialog +class AFX_EXT_CLASS TestRunnerDlg : public CDialog, + public CppUnit::TestListener { public: TestRunnerDlg( TestRunnerModel *model, @@ -50,14 +54,10 @@ public: CWnd* pParent = NULL); ~TestRunnerDlg(); - void addError( CppUnit::TestResult *result, - CppUnit::Test *test, - CppUnit::Exception *e ); - void addFailure( CppUnit::TestResult *result, - CppUnit::Test *test, - CppUnit::Exception *e ); - void endTest( CppUnit::TestResult *result, - CppUnit::Test *test ); + // overrided from TestListener; + void startTest( CppUnit::Test *test ); + void addFailure( const CppUnit::TestFailure &failure ); + void endTest( CppUnit::Test *test ); // IDD is not use, it is just there for the wizard. //{{AFX_DATA(TestRunnerDlg) @@ -96,7 +96,8 @@ protected: ProgressBar *m_testsProgress; CppUnit::Test *m_selectedTest; ActiveTest *m_activeTest; - CppUnit::TestResult *m_result; + CppUnit::TestResult *m_testObserver; + CppUnit::TestResultCollector *m_result; int m_testsRun; int m_errors; int m_failures; @@ -114,10 +115,7 @@ protected: errorTypeError }; - void addListEntry( std::string type, - CppUnit::TestResult *result, - CppUnit::Test *test, - CppUnit::Exception *e ); + void addListEntry( const CppUnit::TestFailure &failure ); void beIdle(); void beRunning(); void beRunDisabled(); @@ -140,10 +138,23 @@ protected: TestRunnerModel &model(); void updateHistoryCombo(); -private: + void updateTopButtonPosition( unsigned int buttonId, + int xButtonLeft, + int xButtonRight ); + void updateBottomButtonPosition( unsigned int buttonId, + int xButtonLeft, + int xButtonRight, + int yButtonBottom ); + // layout management void updateLayoutInfo(); + CRect getItemWindowRect( unsigned int itemId ); + CRect getDialogBounds(); + void updateListPosition( int xButtonLeft ); + +private: + int m_margin; /// distance from bottom of ListView diff --git a/src/qttestrunner/TestRunnerModel.cpp b/src/qttestrunner/TestRunnerModel.cpp index 07f8820..ed32302 100644 --- a/src/qttestrunner/TestRunnerModel.cpp +++ b/src/qttestrunner/TestRunnerModel.cpp @@ -144,11 +144,11 @@ TestRunnerModel::startTest( CppUnit::Test *test ) // Called from the TestRunnerThread. void -TestRunnerModel::addFailure( CppUnit::TestFailure *failure ) +TestRunnerModel::addFailure( const CppUnit::TestFailure &failure ) { - addFailureInfo( new TestFailureInfo( failure->failedTest(), - failure->thrownException(), - failure->isError() ) ); + addFailureInfo( new TestFailureInfo( failure.failedTest(), + failure.thrownException(), + failure.isError() ) ); } diff --git a/src/qttestrunner/TestRunnerModel.h b/src/qttestrunner/TestRunnerModel.h index df45bac..9de08e7 100644 --- a/src/qttestrunner/TestRunnerModel.h +++ b/src/qttestrunner/TestRunnerModel.h @@ -87,7 +87,7 @@ private: void startTest( CppUnit::Test *test ); /// Called from the TestRunnerThread. - void addFailure( CppUnit::TestFailure *failure ); + void addFailure( const CppUnit::TestFailure &failure ); /// Called from the TestRunnerThread. void endTest( CppUnit::Test *test ); |