added cppunit unit testing framework, using cmake, stripped out the original build systems.

added starting point for Bullet unit tests, with one example unit test
Enable the option BUILD_UNIT_TESTS in cmake to build the test. Note that the test doesn't automatically run.
This commit is contained in:
erwin.coumans
2010-07-23 22:09:57 +00:00
parent 6f823687b5
commit a983353f34
139 changed files with 15575 additions and 0 deletions

View File

@@ -300,4 +300,8 @@ IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
OPTION(INSTALL_EXTRA_LIBS "Set when you want extra libraries installed" OFF)
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
OPTION(BUILD_UNIT_TESTS "Build Unit Tests" OFF)
IF (BUILD_UNIT_TESTS)
SUBDIRS(UnitTests)
ENDIF()

View File

@@ -0,0 +1,17 @@
INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src
${BULLET_PHYSICS_SOURCE_DIR}/UnitTests/cppunit/include
${VECTOR_MATH_INCLUDE}
)
LINK_LIBRARIES(
cppunit BulletMultiThreaded BulletDynamics BulletCollision LinearMath
)
ADD_EXECUTABLE(AppBulletUnitTests
Main.cpp
TestBulletOnly.h
)

View File

@@ -0,0 +1,38 @@
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include "TestBulletOnly.h"
CPPUNIT_TEST_SUITE_REGISTRATION( TestBulletOnly );
int main(int argc, char* argv[])
{
// Create the event manager and test controller
CPPUNIT_NS::TestResult controller;
// Add a listener that colllects test result
CPPUNIT_NS::TestResultCollector result;
controller.addListener( &result );
// Add a listener that print dots as test run.
CPPUNIT_NS::BriefTestProgressListener progress;
controller.addListener( &progress );
// Add the top suite to the test runner
CPPUNIT_NS::TestRunner runner;
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
runner.run( controller );
// Print test in a compiler compatible format.
CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
outputter.write();
getchar();
return result.wasSuccessful() ? 0 : 1;
}

View File

@@ -0,0 +1,122 @@
#ifndef TESTBULLETONLY_HAS_BEEN_INCLUDED
#define TESTBULLETONLY_HAS_BEEN_INCLUDED
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "btBulletDynamicsCommon.h"
#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
// ---------------------------------------------------------------------------
class TestBulletOnly : public CppUnit::TestFixture
{
public:
void setUp()
{
// empty
}
void tearDown()
{
// empty
}
btRigidBody::btRigidBodyConstructionInfo buildConstructionInfo( btScalar mass, btScalar friction, btScalar restitution, btScalar linearDamping,
btScalar angularDamping, btDefaultMotionState & state, btCollisionShape * shape )
{
btVector3 inertia;
shape->calculateLocalInertia( mass, inertia );
btRigidBody::btRigidBodyConstructionInfo info( mass, &state, shape, inertia );
info.m_friction = friction;
info.m_restitution = restitution;
info.m_linearDamping = linearDamping;
info.m_angularDamping = angularDamping;
return info;
}
void testKinematicVelocity0()
{
// Setup the world --
btCollisionConfiguration * mCollisionConfig;
btCollisionDispatcher * mCollisionDispatch;
btBroadphaseInterface * mBroadphase;
btConstraintSolver * mConstraintSolver;
btDiscreteDynamicsWorld * mWorld;
mCollisionConfig = new btDefaultCollisionConfiguration;
mCollisionDispatch = new btCollisionDispatcher( mCollisionConfig );
mBroadphase = new btDbvtBroadphase();
mConstraintSolver = new btSequentialImpulseConstraintSolver();
mWorld = new btDiscreteDynamicsWorld( mCollisionDispatch, mBroadphase, mConstraintSolver, mCollisionConfig );
mWorld->setGravity( btVector3( 0, -9.81, 0 ));
// -- .
// Set up the rigid body --
btCollisionShape * bodyShape = new btBoxShape( btVector3( 1, 1, 1 ) );
btTransform bodyInitial;
btDefaultMotionState mMotionState;
bodyInitial.setIdentity();
bodyInitial.setOrigin( btVector3( 0, 0, 0 ) );
btRigidBody mRigidBody( buildConstructionInfo( 1, 0.5, 0.5, 0, 0, mMotionState, bodyShape ) );
mWorld->addRigidBody( &mRigidBody );
mRigidBody.setMassProps( 1, btVector3( 1, 1, 1 ) );
mRigidBody.updateInertiaTensor();
mRigidBody.setCollisionFlags( btCollisionObject::CF_KINEMATIC_OBJECT );
// -- .
// Interpolate the velocity --
//btVector3 velocity( 1., 2., 3. ), spin( 0.1, 0.2, 0.3 );
btVector3 velocity( 1., 2., 3. ), spin( 0.1, 0.2, .3 );
btTransform interpolated;
// TODO: This is inaccurate for small spins.
btTransformUtil::integrateTransform( mRigidBody.getCenterOfMassTransform(), velocity, spin, 1.0f/60.f, interpolated );
mRigidBody.setInterpolationWorldTransform( interpolated );
// -- .
mWorld->stepSimulation( 1.f/60.f, 60, 1.0f/60.f );
btScalar a = 0.f;
btScalar f = 1.f/a;
CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody.getLinearVelocity().length2(), velocity.length2(), 1e-8 );
#ifdef BT_USE_DOUBLE_PRECISION
CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody.getAngularVelocity().length2(), spin.length2(), 1e-4 );
#else
CPPUNIT_ASSERT_DOUBLES_EQUAL( mRigidBody.getAngularVelocity().length2(), spin.length2(), 5e-3 );
#endif //CPPUNIT_ASSERT_DOUBLES_EQUAL
delete mWorld;
delete mConstraintSolver;
delete mBroadphase;
delete mCollisionDispatch;
delete mCollisionConfig;
delete bodyShape;
}
CPPUNIT_TEST_SUITE(TestBulletOnly);
CPPUNIT_TEST(testKinematicVelocity0);
CPPUNIT_TEST_SUITE_END();
private:
};
#endif

2
UnitTests/CMakeLists.txt Normal file
View File

@@ -0,0 +1,2 @@
SUBDIRS( cppunit BulletUnitTests)

View File

@@ -0,0 +1,6 @@
Michael Feathers <mfeathers@objectmentor.com>
Jerome Lacoste <lacostej@altern.org>
E. Sommerlade <eric@sommerla.de>
Baptiste Lepilleur <gaiacrtn@free.fr> <blep@sourceforge.net>
Bastiaan Bakker <bastiaan.bakker@lifeline.nl>
Steve Robbins <smr99@sourceforge.net>

6
UnitTests/cppunit/BUGS Normal file
View File

@@ -0,0 +1,6 @@
KNOWN BUGS
----------
The handling of html and man pages in doc/Makefile.am is
flawed. It will not pass "make distcheck".

View File

@@ -0,0 +1,74 @@
INCLUDE_DIRECTORIES(
include
)
ADD_LIBRARY(cppunit
#core
src/cppunit/AdditionalMessage.cpp
src/cppunit/Asserter.cpp
src/cppunit/Exception.cpp
src/cppunit/Message.cpp
src/cppunit/SourceLine.cpp
src/cppunit/SynchronizedObject.cpp
src/cppunit/Test.cpp
src/cppunit/TestAssert.cpp
src/cppunit/TestCase.cpp
src/cppunit/TestComposite.cpp
src/cppunit/TestFailure.cpp
src/cppunit/TestLeaf.cpp
src/cppunit/TestPath.cpp
src/cppunit/TestResult.cpp
src/cppunit/TestRunner.cpp
src/cppunit/TestSuite.cpp
#extension
src/cppunit/RepeatedTest.cpp
src/cppunit/TestCaseDecorator.cpp
src/cppunit/TestDecorator.cpp
src/cppunit/TestSetUp.cpp
#helper
src/cppunit/TestFactoryRegistry.cpp
src/cppunit/TestNamer.cpp
src/cppunit/TestSuiteBuilderContext.cpp
src/cppunit/TypeInfoHelper.cpp
#listener
src/cppunit/BriefTestProgressListener.cpp
src/cppunit/TestResultCollector.cpp
src/cppunit/TestSuccessListener.cpp
src/cppunit/TextTestProgressListener.cpp
src/cppunit/TextTestResult.cpp
#output
src/cppunit/CompilerOutputter.cpp
src/cppunit/TextOutputter.cpp
src/cppunit/XmlOutputter.cpp
src/cppunit/XmlOutputterHook.cpp
#plugin
src/cppunit/BeOsDynamicLibraryManager.cpp
src/cppunit/DynamicLibraryManager.cpp
src/cppunit/DynamicLibraryManagerException.cpp
src/cppunit/PlugInManager.cpp
src/cppunit/PlugInParameters.cpp
src/cppunit/ShlDynamicLibraryManager.cpp
src/cppunit/TestPlugInDefaultImpl.cpp
src/cppunit/UnixDynamicLibraryManager.cpp
src/cppunit/Win32DynamicLibraryManager.cpp
#protector
src/cppunit/DefaultProtector.cpp
src/cppunit/Protector.cpp
src/cppunit/ProtectorChain.cpp
#textui
src/cppunit/TextTestRunner.cpp
#tools
src/cppunit/StringTools.cpp
src/cppunit/XmlDocument.cpp
src/cppunit/XmlElement.cpp
)

3749
UnitTests/cppunit/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
CppUnit's coding guidelines for portability:
--------------------------------------------
- don't explicitly declare CppUnit namespace, instead use macro
CPPUNIT_NS_BEGIN and CPPUNIT_NS_END.
- don't explicitly use 'CppUnit' to refer to class in CppUnit namespace,
instead use macro CPPUNIT_NS which expands to either 'CppUnit' or
nothing depending on the configuration.
- don't use the 'using directive', always use full qualification. For STL,
always use std::.
- don't use C++ style cast directly, instead use CppUnit's cast macro
(CPPUNIT_CONST_CAST).
- don't use the mutable keyword, instead do a const cast.
- don't use the typename keyword in template declaration, instead use 'class'.
- don't make use of RTTI (typeid) or dynamic_cast mandatory.
- don't use STL container directly, instead use CppUnit's wrapper located
in include/cppunit/portability. This help support compilers that don't
support default template parameter and require an allocator to be
specified.
- don't use default template parameters. If needed, use STLPort wrapper
technic (see include/cppunit/portability/).
- don't use templatized member functions (template method declared inside a
class), instead declares them as simple template functions (even
mainstream compiler such as VC++ 6 as trouble with them).
- don't use default parameter value in template function. Not supported
by all compiler (on OS/390 for instance).
- don't use STL container at() method, instead use the array accessor [].
at() is not supported on some gcc versions.
- dereferencing containers must be done by (*ref_ptr).data instead of
ref_ptr->data.
In brief, it should be possible to compile CppUnit on a C++ compiler that do
not have the following features:
- C++ style cast
- mutable and typename keyword
- RTTI
- template default parameters
- templatized member functions (that is a template function declared within a
class).
- namespace
As such, usage of those features should always be optional.
Following those guidelines should allow to compile on most compilers, as long
as STL are available (in std namespace or not), with some form of strstream and
iostream, as well as exception support.
--
Baptiste Lepilleur <gaiacrtn@free.fr>

23
UnitTests/cppunit/THANKS Normal file
View File

@@ -0,0 +1,23 @@
Tim Jansen <timj@systembureau.com>
Christian Leutloff <leutloff@debian.org>
Steve M. Robbins <smr@sumost.ca>
Patrick Berny <PPBerny@web.de>
Patrick Hartling
Peer Sommerlund
Duane Murphy <duanem@users.sourceforge.net>
Gigi Sayfan <gigi@morphink.com>
Armin "bored" Michel <bored@sourceforge.net>
Jeffrey Morgan <kuzman@zoominternet.net>
'cuppa' project team (http://sourceforge.jp/projects/cuppa/)
Phil Verghese <philv@users.sourceforge.net>
Lavoie Philippe <lavoie@yukon.genie.uottawa.ca>
Pavel Zabelin
Marco Welti <Welti@GretagMacbeth.ch>
Thomas Neidhart
Hans B<>hler <hans.buehler@topmail.de> (Dynamic Window library used by MFC UI)
John Sisson
Steven Mitter <smitter@iicm.tu-graz.ac.at>
Stephan Stapel <stephan.stapel@web.de>
Abdessattar Sassi <abdesassi@users.sourceforge.net> (hp-ux plug-in support)
Max Quatember and Andreas Pfaffenbichler (VC++ 7 MFC TestRunner go to source line)
Vincent Rivi<76>re

35
UnitTests/cppunit/TODO Normal file
View File

@@ -0,0 +1,35 @@
* Bugs:
Asserter::makeNotEqualMessage() strip the shortDescription of the additional message.
* CppUnit:
- STL concept checker.
- Memory leak tracking: setUp/tearDown should be leak safe if no failure occured.
* UnitTest
- add tests for XmlOutputter::setStyleSheet (current assertion macro strip <?...> when
testing )
* VC++ TestRunner:
- Modify MfcUi::TestRunner to expose TestResult (which allow specific TestListener
for global initialization).
- Update MfcTestRunner to use TestPath to store test in the registry
* Documentation:
CookBook:
- how to create simple test cases (with CppUnit namespace)
- test case using only CPPUINT_ASSERT
- test case using CPPUNIT_ASSERT_EQUAL
- advanced assertions with the CPPUNIT_ASSERT_MESSAGE
- Helper Macros for convenience
- Creating a suite
- Composing a suite from more suites (i.e. compose tests for n modules to
form a big test for the whole program)
- customizing output using an user defined TestListener
- how to write the TestListener (subclass of TestListener)
- how to hook it in
- how to use the GUI
- MSVC++ special stuff
- other custmization stuff I haven't understood yet
CppUnit: architecture overview.

View File

@@ -0,0 +1,76 @@
#ifndef CPPUNIT_ADDITIONALMESSAGE_H
#define CPPUNIT_ADDITIONALMESSAGE_H
#include <cppunit/Message.h>
CPPUNIT_NS_BEGIN
/*! \brief An additional Message for assertions.
* \ingroup CreatingNewAssertions
*
* Provides a implicit constructor that takes a single string. This allow this
* class to be used as the message arguments in macros.
*
* The constructed object is either a Message with a single detail string if
* a string was passed to the macro, or a copy of the Message passed to the macro.
*
* Here is an example of usage:
* \code
*
* void checkStringEquals( const std::string &expected,
* const std::string &actual,
* const CppUnit::SourceLine &sourceLine,
* const CppUnit::AdditionalMessage &message );
*
* #define XTLUT_ASSERT_STRING_EQUAL_MESSAGE( expected, actual, message ) \
* ::XtlUt::Impl::checkStringEquals( ::Xtl::toString(expected), \
* ::Xtl::toString(actual), \
* CPPUNIT_SOURCELINE(), \
* message )
* \endcode
*
* In the previous example, the user can specify a simple string for \a message,
* or a complex Message object.
*
* \see Message
*/
class CPPUNIT_API AdditionalMessage : public Message
{
public:
typedef Message SuperClass;
/// Constructs an empty Message.
AdditionalMessage();
/*! \brief Constructs a Message with the specified detail string.
* \param detail1 Detail string of the message. If empty, then it is not added.
*/
AdditionalMessage( const std::string &detail1 );
/*! \brief Constructs a Message with the specified detail string.
* \param detail1 Detail string of the message. If empty, then it is not added.
*/
AdditionalMessage( const char *detail1 );
/*! \brief Constructs a copy of the specified message.
* \param other Message to copy.
*/
AdditionalMessage( const Message &other );
/*! \brief Assignment operator.
* \param other Message to copy.
* \return Reference on this object.
*/
AdditionalMessage &operator =( const Message &other );
private:
};
CPPUNIT_NS_END
#endif // CPPUNIT_ADDITIONALMESSAGE_H

View File

@@ -0,0 +1,143 @@
#ifndef CPPUNIT_ASSERTER_H
#define CPPUNIT_ASSERTER_H
#include <cppunit/AdditionalMessage.h>
#include <cppunit/SourceLine.h>
#include <string>
CPPUNIT_NS_BEGIN
class Message;
/*! \brief A set of functions to help writing assertion macros.
* \ingroup CreatingNewAssertions
*
* Here is an example of assertion, a simplified version of the
* actual assertion implemented in examples/cppunittest/XmlUniformiser.h:
* \code
* #include <cppunit/SourceLine.h>
* #include <cppunit/TestAssert.h>
*
* void
* checkXmlEqual( std::string expectedXml,
* std::string actualXml,
* CppUnit::SourceLine sourceLine )
* {
* std::string expected = XmlUniformiser( expectedXml ).stripped();
* std::string actual = XmlUniformiser( actualXml ).stripped();
*
* if ( expected == actual )
* return;
*
* ::CppUnit::Asserter::failNotEqual( expected,
* actual,
* sourceLine );
* }
*
* /// Asserts that two XML strings are equivalent.
* #define CPPUNITTEST_ASSERT_XML_EQUAL( expected, actual ) \
* checkXmlEqual( expected, actual, \
* CPPUNIT_SOURCELINE() )
* \endcode
*/
struct Asserter
{
/*! \brief Throws a Exception with the specified message and location.
*/
static void CPPUNIT_API fail( const Message &message,
const SourceLine &sourceLine = SourceLine() );
/*! \brief Throws a Exception with the specified message and location.
* \deprecated Use fail( Message, SourceLine ) instead.
*/
static void CPPUNIT_API fail( std::string message,
const SourceLine &sourceLine = SourceLine() );
/*! \brief Throws a Exception with the specified message and location.
* \param shouldFail if \c true then the exception is thrown. Otherwise
* nothing happen.
* \param message Message explaining the assertion failiure.
* \param sourceLine Location of the assertion.
*/
static void CPPUNIT_API failIf( bool shouldFail,
const Message &message,
const SourceLine &sourceLine = SourceLine() );
/*! \brief Throws a Exception with the specified message and location.
* \deprecated Use failIf( bool, Message, SourceLine ) instead.
* \param shouldFail if \c true then the exception is thrown. Otherwise
* nothing happen.
* \param message Message explaining the assertion failiure.
* \param sourceLine Location of the assertion.
*/
static void CPPUNIT_API failIf( bool shouldFail,
std::string message,
const SourceLine &sourceLine = SourceLine() );
/*! \brief Returns a expected value string for a message.
* Typically used to create 'not equal' message, or to check that a message
* contains the expected content when writing unit tests for your custom
* assertions.
*
* \param expectedValue String that represents the expected value.
* \return \a expectedValue prefixed with "Expected: ".
* \see makeActual().
*/
static std::string CPPUNIT_API makeExpected( const std::string &expectedValue );
/*! \brief Returns an actual value string for a message.
* Typically used to create 'not equal' message, or to check that a message
* contains the expected content when writing unit tests for your custom
* assertions.
*
* \param actualValue String that represents the actual value.
* \return \a actualValue prefixed with "Actual : ".
* \see makeExpected().
*/
static std::string CPPUNIT_API makeActual( const std::string &actualValue );
static Message CPPUNIT_API makeNotEqualMessage( const std::string &expectedValue,
const std::string &actualValue,
const AdditionalMessage &additionalMessage = AdditionalMessage(),
const std::string &shortDescription = "equality assertion failed");
/*! \brief Throws an Exception with the specified message and location.
* \param expected Text describing the expected value.
* \param actual Text describing the actual value.
* \param sourceLine Location of the assertion.
* \param additionalMessage Additional message. Usually used to report
* what are the differences between the expected and actual value.
* \param shortDescription Short description for the failure message.
*/
static void CPPUNIT_API failNotEqual( std::string expected,
std::string actual,
const SourceLine &sourceLine,
const AdditionalMessage &additionalMessage = AdditionalMessage(),
std::string shortDescription = "equality assertion failed" );
/*! \brief Throws an Exception with the specified message and location.
* \param shouldFail if \c true then the exception is thrown. Otherwise
* nothing happen.
* \param expected Text describing the expected value.
* \param actual Text describing the actual value.
* \param sourceLine Location of the assertion.
* \param additionalMessage Additional message. Usually used to report
* where the "difference" is located.
* \param shortDescription Short description for the failure message.
*/
static void CPPUNIT_API failNotEqualIf( bool shouldFail,
std::string expected,
std::string actual,
const SourceLine &sourceLine,
const AdditionalMessage &additionalMessage = AdditionalMessage(),
std::string shortDescription = "equality assertion failed" );
};
CPPUNIT_NS_END
#endif // CPPUNIT_ASSERTER_H

View File

@@ -0,0 +1,43 @@
#ifndef CPPUNIT_BRIEFTESTPROGRESSLISTENER_H
#define CPPUNIT_BRIEFTESTPROGRESSLISTENER_H
#include <cppunit/TestListener.h>
CPPUNIT_NS_BEGIN
/*! \brief TestListener that prints the name of each test before running it.
* \ingroup TrackingTestExecution
*/
class CPPUNIT_API BriefTestProgressListener : public TestListener
{
public:
/*! Constructs a BriefTestProgressListener object.
*/
BriefTestProgressListener();
/// Destructor.
virtual ~BriefTestProgressListener();
void startTest( Test *test );
void addFailure( const TestFailure &failure );
void endTest( Test *test );
private:
/// Prevents the use of the copy constructor.
BriefTestProgressListener( const BriefTestProgressListener &copy );
/// Prevents the use of the copy operator.
void operator =( const BriefTestProgressListener &copy );
private:
bool m_lastTestFailed;
};
CPPUNIT_NS_END
#endif // CPPUNIT_BRIEFTESTPROGRESSLISTENER_H

View File

@@ -0,0 +1,146 @@
#ifndef CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H
#define CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H
#include <cppunit/Portability.h>
#include <cppunit/Outputter.h>
#include <cppunit/portability/Stream.h>
CPPUNIT_NS_BEGIN
class Exception;
class SourceLine;
class Test;
class TestFailure;
class TestResultCollector;
/*!
* \brief Outputs a TestResultCollector in a compiler compatible format.
* \ingroup WritingTestResult
*
* Printing the test results in a compiler compatible format (assertion
* location has the same format as compiler error), allow you to use your
* IDE to jump to the assertion failure. Location format can be customized (see
* setLocationFormat() ).
*
* For example, when running the test in a post-build with VC++, if an assertion
* fails, you can jump to the assertion by pressing F4 (jump to next error).
*
* Heres is an example of usage (from examples/cppunittest/CppUnitTestMain.cpp):
* \code
* 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::TextUi::TestRunner runner;
* runner.addTest( CppUnitTest::suite() ); // Add the top suite to the test runner
*
* if ( selfTest )
* { // Change the default outputter to a compiler error format outputter
* // The test runner owns the new outputter.
* runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
* std::cerr ) );
* }
*
* // Run the test and don't wait a key if post build check.
* bool wasSuccessful = runner.run( "", !selfTest );
*
* // Return error code 1 if the one of test failed.
* return wasSuccessful ? 0 : 1;
* }
* \endcode
*/
class CPPUNIT_API CompilerOutputter : public Outputter
{
public:
/*! \brief Constructs a CompilerOutputter object.
* \param result Result of the test run.
* \param stream Stream used to output test result.
* \param locationFormat Error location format used by your compiler. Default
* to \c CPPUNIT_COMPILER_LOCATION_FORMAT which is defined
* in the configuration file. See setLocationFormat() for detail.
* \see setLocationFormat().
*/
CompilerOutputter( TestResultCollector *result,
OStream &stream,
const std::string &locationFormat = CPPUNIT_COMPILER_LOCATION_FORMAT );
/// Destructor.
virtual ~CompilerOutputter();
/*! \brief Sets the error location format.
*
* Indicates the format used to report location of failed assertion. This format should
* match the one used by your compiler.
*
* The location format is a string in which the occurence of the following character
* sequence are replaced:
*
* - "%l" => replaced by the line number
* - "%p" => replaced by the full path name of the file ("G:\prg\vc\cppunit\MyTest.cpp")
* - "%f" => replaced by the base name of the file ("MyTest.cpp")
*
* Some examples:
*
* - VC++ error location format: "%p(%l):" => produce "G:\prg\MyTest.cpp(43):"
* - GCC error location format: "%f:%l:" => produce "MyTest.cpp:43:"
*
* Thoses are the two compilers currently <em>supported</em> (gcc format is used if
* VC++ is not detected). If you want your compiler to be automatically supported by
* CppUnit, send a mail to the mailing list (preferred), or submit a feature request
* that indicates how to detect your compiler with the preprocessor (\#ifdef...) and
* your compiler location format.
*/
void setLocationFormat( const std::string &locationFormat );
/*! \brief Creates an instance of an outputter that matches your current compiler.
* \deprecated This class is specialized through parameterization instead of subclassing...
* Use CompilerOutputter::CompilerOutputter instead.
*/
static CompilerOutputter *defaultOutputter( TestResultCollector *result,
OStream &stream );
void write();
void setNoWrap();
void setWrapColumn( int wrapColumn );
int wrapColumn() const;
virtual void printSuccess();
virtual void printFailureReport();
virtual void printFailuresList();
virtual void printStatistics();
virtual void printFailureDetail( TestFailure *failure );
virtual void printFailureLocation( SourceLine sourceLine );
virtual void printFailureType( TestFailure *failure );
virtual void printFailedTestName( TestFailure *failure );
virtual void printFailureMessage( TestFailure *failure );
private:
/// Prevents the use of the copy constructor.
CompilerOutputter( const CompilerOutputter &copy );
/// Prevents the use of the copy operator.
void operator =( const CompilerOutputter &copy );
virtual bool processLocationFormatCommand( char command,
const SourceLine &sourceLine );
virtual std::string extractBaseName( const std::string &fileName ) const;
private:
TestResultCollector *m_result;
OStream &m_stream;
std::string m_locationFormat;
int m_wrapColumn;
};
CPPUNIT_NS_END
#endif // CPPUNIT_COMPILERTESTRESULTOUTPUTTER_H

View File

@@ -0,0 +1,90 @@
#ifndef CPPUNIT_EXCEPTION_H
#define CPPUNIT_EXCEPTION_H
#include <cppunit/Portability.h>
#include <cppunit/Message.h>
#include <cppunit/SourceLine.h>
#include <exception>
CPPUNIT_NS_BEGIN
/*! \brief Exceptions thrown by failed assertions.
* \ingroup BrowsingCollectedTestResult
*
* Exception is an exception that serves
* descriptive strings through its what() method
*/
class CPPUNIT_API Exception : public std::exception
{
public:
/*! \brief Constructs the exception with the specified message and source location.
* \param message Message associated to the exception.
* \param sourceLine Source location related to the exception.
*/
Exception( const Message &message = Message(),
const SourceLine &sourceLine = SourceLine() );
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
/*!
* \deprecated Use other constructor instead.
*/
Exception( std::string message,
long lineNumber,
std::string fileName );
#endif
/*! \brief Constructs a copy of an exception.
* \param other Exception to copy.
*/
Exception( const Exception &other );
/// Destructs the exception
virtual ~Exception() throw();
/// Performs an assignment
Exception &operator =( const Exception &other );
/// Returns descriptive message
const char *what() const throw();
/// Location where the error occured
SourceLine sourceLine() const;
/// Message related to the exception.
Message message() const;
/// Set the message.
void setMessage( const Message &message );
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
/// The line on which the error occurred
long lineNumber() const;
/// The file in which the error occurred
std::string fileName() const;
static const std::string UNKNOWNFILENAME;
static const long UNKNOWNLINENUMBER;
#endif
/// Clones the exception.
virtual Exception *clone() const;
protected:
// VC++ does not recognize call to parent class when prefixed
// with a namespace. This is a workaround.
typedef std::exception SuperClass;
Message m_message;
SourceLine m_sourceLine;
std::string m_whatMessage;
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXCEPTION_H

View File

@@ -0,0 +1,156 @@
#ifndef CPPUNIT_MESSAGE_H
#define CPPUNIT_MESSAGE_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/portability/CppUnitDeque.h>
#include <string>
CPPUNIT_NS_BEGIN
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::deque<std::string>;
#endif
/*! \brief Message associated to an Exception.
* \ingroup CreatingNewAssertions
* A message is composed of two items:
* - a short description (~20/30 characters)
* - a list of detail strings
*
* The short description is used to indicate how the detail strings should be
* interpreted. It usually indicates the failure types, such as
* "assertion failed", "forced failure", "unexpected exception caught",
* "equality assertion failed"... It should not contains new line character (\n).
*
* Detail strings are used to provide more information about the failure. It
* can contains the asserted expression, the expected and actual values in an
* equality assertion, some addional messages... Detail strings can contains
* new line characters (\n).
*/
class CPPUNIT_API Message
{
public:
Message();
// Ensure thread-safe copy by detaching the string.
Message( const Message &other );
explicit Message( const std::string &shortDescription );
Message( const std::string &shortDescription,
const std::string &detail1 );
Message( const std::string &shortDescription,
const std::string &detail1,
const std::string &detail2 );
Message( const std::string &shortDescription,
const std::string &detail1,
const std::string &detail2,
const std::string &detail3 );
Message &operator =( const Message &other );
/*! \brief Returns the short description.
* \return Short description.
*/
const std::string &shortDescription() const;
/*! \brief Returns the number of detail string.
* \return Number of detail string.
*/
int detailCount() const;
/*! \brief Returns the detail at the specified index.
* \param index Zero based index of the detail string to return.
* \returns Detail string at the specified index.
* \exception std::invalid_argument if \a index < 0 or index >= detailCount().
*/
std::string detailAt( int index ) const;
/*! \brief Returns a string that represents a list of the detail strings.
*
* Example:
* \code
* Message message( "not equal", "Expected: 3", "Actual: 7" );
* std::string details = message.details();
* // details contains:
* // "- Expected: 3\n- Actual: 7\n" \endcode
*
* \return A string that is a concatenation of all the detail strings. Each detail
* string is prefixed with '- ' and suffixed with '\n' before being
* concatenated to the other.
*/
std::string details() const;
/*! \brief Removes all detail strings.
*/
void clearDetails();
/*! \brief Adds a single detail string.
* \param detail Detail string to add.
*/
void addDetail( const std::string &detail );
/*! \brief Adds two detail strings.
* \param detail1 Detail string to add.
* \param detail2 Detail string to add.
*/
void addDetail( const std::string &detail1,
const std::string &detail2 );
/*! \brief Adds three detail strings.
* \param detail1 Detail string to add.
* \param detail2 Detail string to add.
* \param detail3 Detail string to add.
*/
void addDetail( const std::string &detail1,
const std::string &detail2,
const std::string &detail3 );
/*! \brief Adds the detail strings of the specified message.
* \param message All the detail strings of this message are added to this one.
*/
void addDetail( const Message &message );
/*! \brief Sets the short description.
* \param shortDescription New short description.
*/
void setShortDescription( const std::string &shortDescription );
/*! \brief Tests if a message is identical to another one.
* \param other Message this message is compared to.
* \return \c true if the two message are identical, \c false otherwise.
*/
bool operator ==( const Message &other ) const;
/*! \brief Tests if a message is different from another one.
* \param other Message this message is compared to.
* \return \c true if the two message are not identical, \c false otherwise.
*/
bool operator !=( const Message &other ) const;
private:
std::string m_shortDescription;
typedef CppUnitDeque<std::string> Details;
Details m_details;
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_MESSAGE_H

View File

@@ -0,0 +1,26 @@
#ifndef CPPUNIT_OUTPUTTER_H
#define CPPUNIT_OUTPUTTER_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
/*! \brief Abstract outputter to print test result summary.
* \ingroup WritingTestResult
*/
class CPPUNIT_API Outputter
{
public:
/// Destructor.
virtual ~Outputter() {}
virtual void write() =0;
};
CPPUNIT_NS_END
#endif // CPPUNIT_OUTPUTTER_H

View File

@@ -0,0 +1,183 @@
#ifndef CPPUNIT_PORTABILITY_H
#define CPPUNIT_PORTABILITY_H
#if defined(_WIN32) && !defined(WIN32)
# define WIN32 1
#endif
/* include platform specific config */
#if defined(__BORLANDC__)
# include <cppunit/config/config-bcb5.h>
#elif defined (_MSC_VER)
# if _MSC_VER == 1200 && defined(_WIN32_WCE) //evc4
# include <cppunit/config/config-evc4.h>
# else
# include <cppunit/config/config-msvc6.h>
# endif
#else
# include <cppunit/config-auto.h>
#endif
// Version number of package
#ifndef CPPUNIT_VERSION
#define CPPUNIT_VERSION "1.12.0"
#endif
#include <cppunit/config/CppUnitApi.h> // define CPPUNIT_API & CPPUNIT_NEED_DLL_DECL
#include <cppunit/config/SelectDllLoader.h>
/* Options that the library user may switch on or off.
* If the user has not done so, we chose default values.
*/
/* Define to 1 if you wish to have the old-style macros
assert(), assertEqual(), assertDoublesEqual(), and assertLongsEqual() */
#if !defined(CPPUNIT_ENABLE_NAKED_ASSERT)
# define CPPUNIT_ENABLE_NAKED_ASSERT 0
#endif
/* Define to 1 if you wish to have the old-style CU_TEST family
of macros. */
#if !defined(CPPUNIT_ENABLE_CU_TEST_MACROS)
# define CPPUNIT_ENABLE_CU_TEST_MACROS 0
#endif
/* Define to 1 if the preprocessor expands (#foo) to "foo" (quotes incl.)
I don't think there is any C preprocess that does NOT support this! */
#if !defined(CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION)
# define CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION 1
#endif
/* Assumes that STL and CppUnit are in global space if the compiler does not
support namespace. */
#if !defined(CPPUNIT_HAVE_NAMESPACES)
# if !defined(CPPUNIT_NO_NAMESPACE)
# define CPPUNIT_NO_NAMESPACE 1
# endif // !defined(CPPUNIT_NO_NAMESPACE)
# if !defined(CPPUNIT_NO_STD_NAMESPACE)
# define CPPUNIT_NO_STD_NAMESPACE 1
# endif // !defined(CPPUNIT_NO_STD_NAMESPACE)
#endif // !defined(CPPUNIT_HAVE_NAMESPACES)
/* Define CPPUNIT_STD_NEED_ALLOCATOR to 1 if you need to specify
* the allocator you used when instantiating STL container. Typically
* used for compilers that do not support template default parameter.
* CPPUNIT_STD_ALLOCATOR will be used as the allocator. Default is
* std::allocator. On some compilers, you may need to change this to
* std::allocator<T>.
*/
#if CPPUNIT_STD_NEED_ALLOCATOR
# if !defined(CPPUNIT_STD_ALLOCATOR)
# define CPPUNIT_STD_ALLOCATOR std::allocator
# endif // !defined(CPPUNIT_STD_ALLOCATOR)
#endif // defined(CPPUNIT_STD_NEED_ALLOCATOR)
// Compiler error location format for CompilerOutputter
// If not define, assumes that it's gcc
// See class CompilerOutputter for format.
#if !defined(CPPUNIT_COMPILER_LOCATION_FORMAT)
#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) )
// gcc/Xcode integration on Mac OS X
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p:%l: "
#else
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%f:%l:"
#endif
#endif
// If CPPUNIT_HAVE_CPP_CAST is defined, then c++ style cast will be used,
// otherwise, C style cast are used.
#if defined( CPPUNIT_HAVE_CPP_CAST )
# define CPPUNIT_CONST_CAST( TargetType, pointer ) \
const_cast<TargetType>( pointer )
# define CPPUNIT_STATIC_CAST( TargetType, pointer ) \
static_cast<TargetType>( pointer )
#else // defined( CPPUNIT_HAVE_CPP_CAST )
# define CPPUNIT_CONST_CAST( TargetType, pointer ) \
((TargetType)( pointer ))
# define CPPUNIT_STATIC_CAST( TargetType, pointer ) \
((TargetType)( pointer ))
#endif // defined( CPPUNIT_HAVE_CPP_CAST )
// If CPPUNIT_NO_STD_NAMESPACE is defined then STL are in the global space.
// => Define macro 'std' to nothing
#if defined(CPPUNIT_NO_STD_NAMESPACE)
# undef std
# define std
#endif // defined(CPPUNIT_NO_STD_NAMESPACE)
// If CPPUNIT_NO_NAMESPACE is defined, then put CppUnit classes in the
// global namespace: the compiler does not support namespace.
#if defined(CPPUNIT_NO_NAMESPACE)
# define CPPUNIT_NS_BEGIN
# define CPPUNIT_NS_END
# define CPPUNIT_NS
#else // defined(CPPUNIT_NO_NAMESPACE)
# define CPPUNIT_NS_BEGIN namespace CppUnit {
# define CPPUNIT_NS_END }
# define CPPUNIT_NS CppUnit
#endif // defined(CPPUNIT_NO_NAMESPACE)
/*! Stringize a symbol.
*
* Use this macro to convert a preprocessor symbol to a string.
*
* Example of usage:
* \code
* #define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTestPlugIn
* const char *name = CPPUNIT_STRINGIZE( CPPUNIT_PLUGIN_EXPORTED_NAME );
* \endcode
*/
#define CPPUNIT_STRINGIZE( symbol ) _CPPUNIT_DO_STRINGIZE( symbol )
/// \internal
#define _CPPUNIT_DO_STRINGIZE( symbol ) #symbol
/*! Joins to symbol after expanding them into string.
*
* Use this macro to join two symbols. Example of usage:
*
* \code
* #define MAKE_UNIQUE_NAME(prefix) CPPUNIT_JOIN( prefix, __LINE__ )
* \endcode
*
* The macro defined in the example concatenate a given prefix with the line number
* to obtain a 'unique' identifier.
*
* \internal From boost documentation:
* The following piece of macro magic joins the two
* arguments together, even when one of the arguments is
* itself a macro (see 16.3.1 in C++ standard). The key
* is that macro expansion of macro arguments does not
* occur in CPPUNIT_JOIN2 but does in CPPUNIT_JOIN.
*/
#define CPPUNIT_JOIN( symbol1, symbol2 ) _CPPUNIT_DO_JOIN( symbol1, symbol2 )
/// \internal
#define _CPPUNIT_DO_JOIN( symbol1, symbol2 ) _CPPUNIT_DO_JOIN2( symbol1, symbol2 )
/// \internal
#define _CPPUNIT_DO_JOIN2( symbol1, symbol2 ) symbol1##symbol2
/// \internal Unique suffix for variable name. Can be overridden in platform specific
/// config-*.h. Default to line number.
#ifndef CPPUNIT_UNIQUE_COUNTER
# define CPPUNIT_UNIQUE_COUNTER __LINE__
#endif
/*! Adds the line number to the specified string to create a unique identifier.
* \param prefix Prefix added to the line number to create a unique identifier.
* \see CPPUNIT_TEST_SUITE_REGISTRATION for an example of usage.
*/
#define CPPUNIT_MAKE_UNIQUE_NAME( prefix ) CPPUNIT_JOIN( prefix, CPPUNIT_UNIQUE_COUNTER )
/*! Defines wrap colunm for %CppUnit. Used by CompilerOuputter.
*/
#if !defined(CPPUNIT_WRAP_COLUMN)
# define CPPUNIT_WRAP_COLUMN 79
#endif
#endif // CPPUNIT_PORTABILITY_H

View File

@@ -0,0 +1,94 @@
#ifndef CPPUNIT_PROTECTOR_H
#define CPPUNIT_PROTECTOR_H
#include <cppunit/SourceLine.h>
CPPUNIT_NS_BEGIN
class Exception;
class Message;
class ProtectorContext;
class TestResult;
class CPPUNIT_API Functor
{
public:
virtual ~Functor();
virtual bool operator()() const =0;
};
/*! \brief Protects one or more test case run.
*
* Protector are used to globably 'decorate' a test case. The most common
* usage of Protector is to catch exception that do not subclass std::exception,
* such as MFC CException class or Rogue Wave RWXMsg class, and capture the
* message associated to the exception. In fact, CppUnit capture message from
* Exception and std::exception using a Protector.
*
* Protector are chained. When you add a Protector using
* TestResult::pushProtector(), your protector is in fact passed as a Functor
* to the first protector of the chain.
*
* TestCase protects call to setUp(), runTest() and tearDown() by calling
* TestResult::protect().
*
* Because the protector chain is handled by TestResult, a protector can be
* active for a single test, or a complete test run.
*
* Here are some possible usages:
* - run all test case in a separate thread and assumes the test failed if it
* did not finish in a given time (infinite loop work around)
* - performance tracing : time only the runTest() time.
* \sa TestResult, TestCase, TestListener.
*/
class CPPUNIT_API Protector
{
public:
virtual ~Protector();
virtual bool protect( const Functor &functor,
const ProtectorContext &context ) =0;
protected:
void reportError( const ProtectorContext &context,
const Exception &error ) const;
void reportError( const ProtectorContext &context,
const Message &message,
const SourceLine &sourceLine = SourceLine() ) const;
void reportFailure( const ProtectorContext &context,
const Exception &failure ) const;
Message actualMessage( const Message &message,
const ProtectorContext &context ) const;
};
/*! \brief Scoped protector push to TestResult.
*
* Adds the specified Protector to the specified TestResult for the object
* life-time.
*/
class CPPUNIT_API ProtectorGuard
{
public:
/// Pushes the specified protector.
ProtectorGuard( TestResult *result,
Protector *protector );
/// Pops the protector.
~ProtectorGuard();
private:
TestResult *m_result;
};
CPPUNIT_NS_END
#endif // CPPUNIT_PROTECTOR_H

View File

@@ -0,0 +1,63 @@
#ifndef CPPUNIT_SOURCELINE_H
#define CPPUNIT_SOURCELINE_H
#include <cppunit/Portability.h>
#include <string>
/*! \brief Constructs a SourceLine object initialized with the location where the macro is expanded.
* \ingroup CreatingNewAssertions
* \relates CppUnit::SourceLine
* Used to write your own assertion macros.
* \see Asserter for example of usage.
*/
#define CPPUNIT_SOURCELINE() CPPUNIT_NS::SourceLine( __FILE__, __LINE__ )
CPPUNIT_NS_BEGIN
/*! \brief Represents a source line location.
* \ingroup CreatingNewAssertions
* \ingroup BrowsingCollectedTestResult
*
* Used to capture the failure location in assertion.
*
* Use the CPPUNIT_SOURCELINE() macro to construct that object. Typically used when
* writing an assertion macro in association with Asserter.
*
* \see Asserter.
*/
class CPPUNIT_API SourceLine
{
public:
SourceLine();
// Ensure thread-safe copy by detaching the string buffer.
SourceLine( const SourceLine &other );
SourceLine( const std::string &fileName,
int lineNumber );
SourceLine &operator =( const SourceLine &other );
/// Destructor.
virtual ~SourceLine();
bool isValid() const;
int lineNumber() const;
std::string fileName() const;
bool operator ==( const SourceLine &other ) const;
bool operator !=( const SourceLine &other ) const;
private:
std::string m_fileName;
int m_lineNumber;
};
CPPUNIT_NS_END
#endif // CPPUNIT_SOURCELINE_H

View File

@@ -0,0 +1,80 @@
#ifndef CPPUNIT_SYNCHRONIZEDOBJECT_H
#define CPPUNIT_SYNCHRONIZEDOBJECT_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
/*! \brief 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 CPPUNIT_API SynchronizedObject
{
public:
/*! \brief Abstract synchronization object (mutex)
*/
class SynchronizationObject
{
public:
SynchronizationObject() {}
virtual ~SynchronizationObject() {}
virtual void lock() {}
virtual void unlock() {}
};
/*! Constructs a SynchronizedObject object.
*/
SynchronizedObject( SynchronizationObject *syncObject =0 );
/// Destructor.
virtual ~SynchronizedObject();
protected:
/*! \brief Locks a synchronization object in the current scope.
*/
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 &copy );
/// Prevents the use of the copy operator.
void operator =( const SynchronizedObject &copy );
};
CPPUNIT_NS_END
#endif // CPPUNIT_SYNCHRONIZEDOBJECT_H

View File

@@ -0,0 +1,117 @@
#ifndef CPPUNIT_TEST_H
#define CPPUNIT_TEST_H
#include <cppunit/Portability.h>
#include <string>
CPPUNIT_NS_BEGIN
class TestResult;
class TestPath;
/*! \brief Base class for all test objects.
* \ingroup BrowsingCollectedTestResult
*
* All test objects should be a subclass of Test. Some test objects,
* TestCase for example, represent one individual test. Other test
* objects, such as TestSuite, are comprised of several tests.
*
* When a Test is run, the result is collected by a TestResult object.
*
* \see TestCase
* \see TestSuite
*/
class CPPUNIT_API Test
{
public:
virtual ~Test() {};
/*! \brief Run the test, collecting results.
*/
virtual void run( TestResult *result ) =0;
/*! \brief Return the number of test cases invoked by run().
*
* The base unit of testing is the class TestCase. This
* method returns the number of TestCase objects invoked by
* the run() method.
*/
virtual int countTestCases () const =0;
/*! \brief Returns the number of direct child of the test.
*/
virtual int getChildTestCount() const =0;
/*! \brief Returns the child test of the specified index.
*
* This method test if the index is valid, then call doGetChildTestAt() if
* the index is valid. Otherwise std::out_of_range exception is thrown.
*
* You should override doGetChildTestAt() method.
*
* \param index Zero based index of the child test to return.
* \return Pointer on the test. Never \c NULL.
* \exception std::out_of_range is \a index is < 0 or >= getChildTestCount().
*/
virtual Test *getChildTestAt( int index ) const;
/*! \brief Returns the test name.
*
* Each test has a name. This name may be used to find the
* test in a suite or registry of tests.
*/
virtual std::string getName () const =0;
/*! \brief Finds the test with the specified name and its parents test.
* \param testName Name of the test to find.
* \param testPath If the test is found, then all the tests traversed to access
* \a test are added to \a testPath, including \c this and \a test.
* \return \c true if a test with the specified name is found, \c false otherwise.
*/
virtual bool findTestPath( const std::string &testName,
TestPath &testPath ) const;
/*! \brief Finds the specified test and its parents test.
* \param test Test to find.
* \param testPath If the test is found, then all the tests traversed to access
* \a test are added to \a testPath, including \c this and \a test.
* \return \c true if the specified test is found, \c false otherwise.
*/
virtual bool findTestPath( const Test *test,
TestPath &testPath ) const;
/*! \brief Finds the test with the specified name in the hierarchy.
* \param testName Name of the test to find.
* \return Pointer on the first test found that is named \a testName. Never \c NULL.
* \exception std::invalid_argument if no test named \a testName is found.
*/
virtual Test *findTest( const std::string &testName ) const;
/*! \brief Resolved the specified test path with this test acting as 'root'.
* \param testPath Test path string to resolve.
* \return Resolved TestPath.
* \exception std::invalid_argument if \a testPath could not be resolved.
* \see TestPath.
*/
virtual TestPath resolveTestPath( const std::string &testPath ) const;
protected:
/*! Throws an exception if the specified index is invalid.
* \param index Zero base index of a child test.
* \exception std::out_of_range is \a index is < 0 or >= getChildTestCount().
*/
virtual void checkIsValidIndex( int index ) const;
/*! \brief Returns the child test of the specified valid index.
* \param index Zero based valid index of the child test to return.
* \return Pointer on the test. Never \c NULL.
*/
virtual Test *doGetChildTestAt( int index ) const =0;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TEST_H

View File

@@ -0,0 +1,428 @@
#ifndef CPPUNIT_TESTASSERT_H
#define CPPUNIT_TESTASSERT_H
#include <cppunit/Portability.h>
#include <cppunit/Exception.h>
#include <cppunit/Asserter.h>
#include <cppunit/portability/Stream.h>
#include <stdio.h>
#include <float.h> // For struct assertion_traits<double>
CPPUNIT_NS_BEGIN
/*! \brief Traits used by CPPUNIT_ASSERT_EQUAL().
*
* Here is an example of specialising these traits:
*
* \code
* template<>
* struct assertion_traits<std::string> // specialization for the std::string type
* {
* static bool equal( const std::string& x, const std::string& y )
* {
* return x == y;
* }
*
* static std::string toString( const std::string& x )
* {
* std::string text = '"' + x + '"'; // adds quote around the string to see whitespace
* OStringStream ost;
* ost << text;
* return ost.str();
* }
* };
* \endcode
*/
template <class T>
struct assertion_traits
{
static bool equal( const T& x, const T& y )
{
return x == y;
}
static std::string toString( const T& x )
{
OStringStream ost;
ost << x;
return ost.str();
}
};
/*! \brief Traits used by CPPUNIT_ASSERT_DOUBLES_EQUAL().
*
* This specialisation from @c struct @c assertion_traits<> ensures that
* doubles are converted in full, instead of being rounded to the default
* 6 digits of precision. Use the system defined ISO C99 macro DBL_DIG
* within float.h is available to define the maximum precision, otherwise
* use the hard-coded maximum precision of 15.
*/
template <>
struct assertion_traits<double>
{
static bool equal( double x, double y )
{
return x == y;
}
static std::string toString( double x )
{
#ifdef DBL_DIG
const int precision = DBL_DIG;
#else
const int precision = 15;
#endif // #ifdef DBL_DIG
char buffer[128];
#ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
sprintf_s(buffer, sizeof(buffer), "%.*g", precision, x);
#else
sprintf(buffer, "%.*g", precision, x);
#endif
return buffer;
}
};
/*! \brief (Implementation) Asserts that two objects of the same type are equals.
* Use CPPUNIT_ASSERT_EQUAL instead of this function.
* \sa assertion_traits, Asserter::failNotEqual().
*/
template <class T>
void assertEquals( const T& expected,
const T& actual,
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,
message );
}
}
/*! \brief (Implementation) Asserts that two double are equals given a tolerance.
* Use CPPUNIT_ASSERT_DOUBLES_EQUAL instead of this function.
* \sa Asserter::failNotEqual().
* \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion.
*/
void CPPUNIT_API assertDoubleEquals( double expected,
double actual,
double delta,
SourceLine sourceLine,
const std::string &message );
/* A set of macros which allow us to get the line number
* and file name at the point of an error.
* Just goes to show that preprocessors do have some
* redeeming qualities.
*/
#if CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION
/** Assertions that a condition is \c true.
* \ingroup Assertions
*/
#define CPPUNIT_ASSERT(condition) \
( CPPUNIT_NS::Asserter::failIf( !(condition), \
CPPUNIT_NS::Message( "assertion failed", \
"Expression: " #condition), \
CPPUNIT_SOURCELINE() ) )
#else
#define CPPUNIT_ASSERT(condition) \
( CPPUNIT_NS::Asserter::failIf( !(condition), \
CPPUNIT_NS::Message( "assertion failed" ), \
CPPUNIT_SOURCELINE() ) )
#endif
/** Assertion with a user specified message.
* \ingroup Assertions
* \param message Message reported in diagnostic if \a condition evaluates
* to \c false.
* \param condition If this condition evaluates to \c false then the
* test failed.
*/
#define CPPUNIT_ASSERT_MESSAGE(message,condition) \
( CPPUNIT_NS::Asserter::failIf( !(condition), \
CPPUNIT_NS::Message( "assertion failed", \
"Expression: " \
#condition, \
message ), \
CPPUNIT_SOURCELINE() ) )
/** Fails with the specified message.
* \ingroup Assertions
* \param message Message reported in diagnostic.
*/
#define CPPUNIT_FAIL( message ) \
( CPPUNIT_NS::Asserter::fail( CPPUNIT_NS::Message( "forced failure", \
message ), \
CPPUNIT_SOURCELINE() ) )
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
/// Generalized macro for primitive value comparisons
#define CPPUNIT_ASSERT_EQUAL(expected,actual) \
( CPPUNIT_NS::assertEquals( (expected), \
(actual), \
__LINE__, __FILE__ ) )
#else
/** Asserts that two values are equals.
* \ingroup Assertions
*
* Equality and string representation can be defined with
* an appropriate CppUnit::assertion_traits class.
*
* A diagnostic is printed if actual and expected values disagree.
*
* Requirement for \a expected and \a actual parameters:
* - They are exactly of the same type
* - They are serializable into a std::strstream using operator <<.
* - They can be compared using operator ==.
*
* The last two requirements (serialization and comparison) can be
* removed by specializing the CppUnit::assertion_traits.
*/
#define CPPUNIT_ASSERT_EQUAL(expected,actual) \
( CPPUNIT_NS::assertEquals( (expected), \
(actual), \
CPPUNIT_SOURCELINE(), \
"" ) )
/** Asserts that two values are equals, provides additional message on failure.
* \ingroup Assertions
*
* Equality and string representation can be defined with
* an appropriate assertion_traits class.
*
* A diagnostic is printed if actual and expected values disagree.
* The message is printed in addition to the expected and actual value
* to provide additional information.
*
* Requirement for \a expected and \a actual parameters:
* - They are exactly of the same type
* - They are serializable into a std::strstream using operator <<.
* - They can be compared using operator ==.
*
* The last two requirements (serialization and comparison) can be
* removed by specializing the CppUnit::assertion_traits.
*/
#define CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual) \
( CPPUNIT_NS::assertEquals( (expected), \
(actual), \
CPPUNIT_SOURCELINE(), \
(message) ) )
#endif
/*! \brief Macro for primitive double value comparisons.
* \ingroup Assertions
*
* The assertion pass if both expected and actual are finite and
* \c fabs( \c expected - \c actual ) <= \c delta.
* If either \c expected or actual are infinite (+/- inf), the
* assertion pass if \c expected == \c actual.
* If either \c expected or \c actual is a NaN (not a number), then
* the assertion fails.
*/
#define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta) \
( CPPUNIT_NS::assertDoubleEquals( (expected), \
(actual), \
(delta), \
CPPUNIT_SOURCELINE(), \
"" ) )
/*! \brief Macro for primitive double value comparisons, setting a
* user-supplied message in case of failure.
* \ingroup Assertions
* \sa CPPUNIT_ASSERT_DOUBLES_EQUAL for detailed semantic of the assertion.
*/
#define CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(message,expected,actual,delta) \
( CPPUNIT_NS::assertDoubleEquals( (expected), \
(actual), \
(delta), \
CPPUNIT_SOURCELINE(), \
(message) ) )
/** Asserts that the given expression throws an exception of the specified type.
* \ingroup Assertions
* Example of usage:
* \code
* std::vector<int> v;
* CPPUNIT_ASSERT_THROW( v.at( 50 ), std::out_of_range );
* \endcode
*/
# define CPPUNIT_ASSERT_THROW( expression, ExceptionType ) \
CPPUNIT_ASSERT_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \
expression, \
ExceptionType )
// implementation detail
#if CPPUNIT_USE_TYPEINFO_NAME
#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
CPPUNIT_NS::TypeInfoHelper::getClassName( typeid(exception) )
#else
#define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
std::string( no_rtti_message )
#endif // CPPUNIT_USE_TYPEINFO_NAME
// implementation detail
#define CPPUNIT_GET_PARAMETER_STRING( parameter ) #parameter
/** Asserts that the given expression throws an exception of the specified type,
* setting a user supplied message in case of failure.
* \ingroup Assertions
* Example of usage:
* \code
* std::vector<int> v;
* CPPUNIT_ASSERT_THROW_MESSAGE( "- std::vector<int> v;", v.at( 50 ), std::out_of_range );
* \endcode
*/
# define CPPUNIT_ASSERT_THROW_MESSAGE( message, expression, ExceptionType ) \
do { \
bool cpputCorrectExceptionThrown_ = false; \
CPPUNIT_NS::Message cpputMsg_( "expected exception not thrown" ); \
cpputMsg_.addDetail( message ); \
cpputMsg_.addDetail( "Expected: " \
CPPUNIT_GET_PARAMETER_STRING( ExceptionType ) ); \
\
try { \
expression; \
} catch ( const ExceptionType & ) { \
cpputCorrectExceptionThrown_ = true; \
} catch ( const std::exception &e) { \
cpputMsg_.addDetail( "Actual : " + \
CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \
"std::exception or derived") ); \
cpputMsg_.addDetail( std::string("What() : ") + e.what() ); \
} catch ( ... ) { \
cpputMsg_.addDetail( "Actual : unknown."); \
} \
\
if ( cpputCorrectExceptionThrown_ ) \
break; \
\
CPPUNIT_NS::Asserter::fail( cpputMsg_, \
CPPUNIT_SOURCELINE() ); \
} while ( false )
/** Asserts that the given expression does not throw any exceptions.
* \ingroup Assertions
* Example of usage:
* \code
* std::vector<int> v;
* v.push_back( 10 );
* CPPUNIT_ASSERT_NO_THROW( v.at( 0 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_NO_THROW( expression ) \
CPPUNIT_ASSERT_NO_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \
expression )
/** Asserts that the given expression does not throw any exceptions,
* setting a user supplied message in case of failure.
* \ingroup Assertions
* Example of usage:
* \code
* std::vector<int> v;
* v.push_back( 10 );
* CPPUNIT_ASSERT_NO_THROW( "std::vector<int> v;", v.at( 0 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, expression ) \
do { \
CPPUNIT_NS::Message cpputMsg_( "unexpected exception caught" ); \
cpputMsg_.addDetail( message ); \
\
try { \
expression; \
} catch ( const std::exception &e ) { \
cpputMsg_.addDetail( "Caught: " + \
CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \
"std::exception or derived" ) ); \
cpputMsg_.addDetail( std::string("What(): ") + e.what() ); \
CPPUNIT_NS::Asserter::fail( cpputMsg_, \
CPPUNIT_SOURCELINE() ); \
} catch ( ... ) { \
cpputMsg_.addDetail( "Caught: unknown." ); \
CPPUNIT_NS::Asserter::fail( cpputMsg_, \
CPPUNIT_SOURCELINE() ); \
} \
} while ( false )
/** Asserts that an assertion fail.
* \ingroup Assertions
* Use to test assertions.
* Example of usage:
* \code
* CPPUNIT_ASSERT_ASSERTION_FAIL( CPPUNIT_ASSERT( 1 == 2 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_ASSERTION_FAIL( assertion ) \
CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception )
/** Asserts that an assertion fail, with a user-supplied message in
* case of error.
* \ingroup Assertions
* Use to test assertions.
* Example of usage:
* \code
* CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( "1 == 2", CPPUNIT_ASSERT( 1 == 2 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( message, assertion ) \
CPPUNIT_ASSERT_THROW_MESSAGE( message, assertion, CPPUNIT_NS::Exception )
/** Asserts that an assertion pass.
* \ingroup Assertions
* Use to test assertions.
* Example of usage:
* \code
* CPPUNIT_ASSERT_ASSERTION_PASS( CPPUNIT_ASSERT( 1 == 1 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_ASSERTION_PASS( assertion ) \
CPPUNIT_ASSERT_NO_THROW( assertion )
/** Asserts that an assertion pass, with a user-supplied message in
* case of failure.
* \ingroup Assertions
* Use to test assertions.
* Example of usage:
* \code
* CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( "1 != 1", CPPUNIT_ASSERT( 1 == 1 ) );
* \endcode
*/
# define CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( message, assertion ) \
CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, assertion )
// Backwards compatibility
#if CPPUNIT_ENABLE_NAKED_ASSERT
#undef assert
#define assert(c) CPPUNIT_ASSERT(c)
#define assertEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a)
#define assertDoublesEqual(e,a,d) CPPUNIT_ASSERT_DOUBLES_EQUAL(e,a,d)
#define assertLongsEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a)
#endif
CPPUNIT_NS_END
#endif // CPPUNIT_TESTASSERT_H

View File

@@ -0,0 +1,204 @@
#ifndef CPPUNIT_TESTCALLER_H // -*- C++ -*-
#define CPPUNIT_TESTCALLER_H
#include <cppunit/Exception.h>
#include <cppunit/TestCase.h>
#if CPPUNIT_USE_TYPEINFO_NAME
# include <cppunit/extensions/TypeInfoHelper.h>
#endif
CPPUNIT_NS_BEGIN
#if 0
/*! \brief Marker class indicating that no exception is expected by TestCaller.
* This class is an implementation detail. You should never use this class directly.
*/
class CPPUNIT_API NoExceptionExpected
{
private:
//! Prevent class instantiation.
NoExceptionExpected();
};
/*! \brief (Implementation) Traits used by TestCaller to expect an exception.
*
* This class is an implementation detail. You should never use this class directly.
*/
template<class ExceptionType>
struct ExpectedExceptionTraits
{
static void expectedException()
{
#if CPPUNIT_USE_TYPEINFO_NAME
throw Exception( Message(
"expected exception not thrown",
"Expected exception type: " +
TypeInfoHelper::getClassName( typeid( ExceptionType ) ) ) );
#else
throw Exception( "expected exception not thrown" );
#endif
}
};
/*! \brief (Implementation) Traits specialization used by TestCaller to
* expect no exception.
*
* This class is an implementation detail. You should never use this class directly.
*/
template<>
struct ExpectedExceptionTraits<NoExceptionExpected>
{
static void expectedException()
{
}
};
#endif
//*** FIXME: rework this when class Fixture is implemented. ***//
/*! \brief Generate a test case from a fixture method.
* \ingroup WritingTestFixture
*
* A test caller provides access to a test case method
* on a test fixture class. Test callers are useful when
* you want to run an individual test or add it to a
* suite.
* Test Callers invoke only one Test (i.e. test method) on one
* Fixture of a TestFixture.
*
* Here is an example:
* \code
* class MathTest : public CppUnit::TestFixture {
* ...
* public:
* void setUp();
* void tearDown();
*
* void testAdd();
* void testSubtract();
* };
*
* CppUnit::Test *MathTest::suite() {
* CppUnit::TestSuite *suite = new CppUnit::TestSuite;
*
* suite->addTest( new CppUnit::TestCaller<MathTest>( "testAdd", testAdd ) );
* return suite;
* }
* \endcode
*
* You can use a TestCaller to bind any test method on a TestFixture
* class, as long as it accepts void and returns void.
*
* \see TestCase
*/
template <class Fixture>
class TestCaller : public TestCase
{
typedef void (Fixture::*TestMethod)();
public:
/*!
* Constructor for TestCaller. This constructor builds a new Fixture
* instance owned by the TestCaller.
* \param name name of this TestCaller
* \param test the method this TestCaller calls in runTest()
*/
TestCaller( std::string name, TestMethod test ) :
TestCase( name ),
m_ownFixture( true ),
m_fixture( new Fixture() ),
m_test( test )
{
}
/*!
* Constructor for TestCaller.
* This constructor does not create a new Fixture instance but accepts
* an existing one as parameter. The TestCaller will not own the
* Fixture object.
* \param name name of this TestCaller
* \param test the method this TestCaller calls in runTest()
* \param fixture the Fixture to invoke the test method on.
*/
TestCaller(std::string name, TestMethod test, Fixture& fixture) :
TestCase( name ),
m_ownFixture( false ),
m_fixture( &fixture ),
m_test( test )
{
}
/*!
* Constructor for TestCaller.
* This constructor does not create a new Fixture instance but accepts
* an existing one as parameter. The TestCaller will own the
* Fixture object and delete it in its destructor.
* \param name name of this TestCaller
* \param test the method this TestCaller calls in runTest()
* \param fixture the Fixture to invoke the test method on.
*/
TestCaller(std::string name, TestMethod test, Fixture* fixture) :
TestCase( name ),
m_ownFixture( true ),
m_fixture( fixture ),
m_test( test )
{
}
~TestCaller()
{
if (m_ownFixture)
delete m_fixture;
}
void runTest()
{
// try {
(m_fixture->*m_test)();
// }
// catch ( ExpectedException & ) {
// return;
// }
// ExpectedExceptionTraits<ExpectedException>::expectedException();
}
void setUp()
{
m_fixture->setUp ();
}
void tearDown()
{
m_fixture->tearDown ();
}
std::string toString() const
{
return "TestCaller " + getName();
}
private:
TestCaller( const TestCaller &other );
TestCaller &operator =( const TestCaller &other );
private:
bool m_ownFixture;
Fixture *m_fixture;
TestMethod m_test;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTCALLER_H

View File

@@ -0,0 +1,55 @@
#ifndef CPPUNIT_TESTCASE_H
#define CPPUNIT_TESTCASE_H
#include <cppunit/Portability.h>
#include <cppunit/TestLeaf.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <string>
CPPUNIT_NS_BEGIN
class TestResult;
/*! \brief A single test object.
*
* This class is used to implement a simple test case: define a subclass
* that overrides the runTest method.
*
* You don't usually need to use that class, but TestFixture and TestCaller instead.
*
* You are expected to subclass TestCase is you need to write a class similiar
* to TestCaller.
*/
class CPPUNIT_API TestCase : public TestLeaf,
public TestFixture
{
public:
TestCase( const std::string &name );
TestCase();
~TestCase();
virtual void run(TestResult *result);
std::string getName() const;
//! FIXME: this should probably be pure virtual.
virtual void runTest();
private:
TestCase( const TestCase &other );
TestCase &operator=( const TestCase &other );
private:
const std::string m_name;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTCASE_H

View File

@@ -0,0 +1,45 @@
#ifndef CPPUNIT_TESTCOMPSITE_H // -*- C++ -*-
#define CPPUNIT_TESTCOMPSITE_H
#include <cppunit/Test.h>
#include <string>
CPPUNIT_NS_BEGIN
/*! \brief A Composite of Tests.
*
* Base class for all test composites. Subclass this class if you need to implement
* a custom TestSuite.
*
* \see Test, TestSuite.
*/
class CPPUNIT_API TestComposite : public Test
{
public:
TestComposite( const std::string &name = "" );
~TestComposite();
void run( TestResult *result );
int countTestCases() const;
std::string getName() const;
private:
TestComposite( const TestComposite &other );
TestComposite &operator =( const TestComposite &other );
virtual void doStartSuite( TestResult *controller );
virtual void doRunChildTests( TestResult *controller );
virtual void doEndSuite( TestResult *controller );
private:
const std::string m_name;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTCOMPSITE_H

View File

@@ -0,0 +1,58 @@
#ifndef CPPUNIT_TESTFAILURE_H // -*- C++ -*-
#define CPPUNIT_TESTFAILURE_H
#include <cppunit/Portability.h>
#include <string>
CPPUNIT_NS_BEGIN
class Exception;
class SourceLine;
class Test;
/*! \brief Record of a failed Test execution.
* \ingroup BrowsingCollectedTestResult
*
* A TestFailure collects a failed test together with
* the caught exception.
*
* TestFailure assumes lifetime control for any exception
* passed to it.
*/
class CPPUNIT_API TestFailure
{
public:
TestFailure( Test *failedTest,
Exception *thrownException,
bool isError );
virtual ~TestFailure ();
virtual Test *failedTest() const;
virtual Exception *thrownException() const;
virtual SourceLine sourceLine() const;
virtual bool isError() const;
virtual std::string failedTestName() const;
virtual TestFailure *clone() const;
protected:
Test *m_failedTest;
Exception *m_thrownException;
bool m_isError;
private:
TestFailure( const TestFailure &other );
TestFailure &operator =( const TestFailure& other );
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTFAILURE_H

View File

@@ -0,0 +1,99 @@
#ifndef CPPUNIT_TESTFIXTURE_H // -*- C++ -*-
#define CPPUNIT_TESTFIXTURE_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
/*! \brief Wraps a test case with setUp and tearDown methods.
* \ingroup WritingTestFixture
*
* A TestFixture is used to provide a common environment for a set
* of test cases.
*
* To define a test fixture, do the following:
* - implement a subclass of TestCase
* - the fixture is defined by instance variables
* - initialize the fixture state by overriding setUp
* (i.e. construct the instance variables of the fixture)
* - clean-up after a test by overriding tearDown.
*
* Each test runs in its own fixture so there
* can be no side effects among test runs.
* Here is an example:
*
* \code
* class MathTest : public CppUnit::TestFixture {
* protected:
* int m_value1, m_value2;
*
* public:
* MathTest() {}
*
* void setUp () {
* m_value1 = 2;
* m_value2 = 3;
* }
* }
* \endcode
*
* For each test implement a method which interacts
* with the fixture. Verify the expected results with assertions specified
* by calling CPPUNIT_ASSERT on the expression you want to test:
*
* \code
* public:
* void testAdd () {
* int result = m_value1 + m_value2;
* CPPUNIT_ASSERT( result == 5 );
* }
* \endcode
*
* Once the methods are defined you can run them. To do this, use
* a TestCaller.
*
* \code
* CppUnit::Test *test = new CppUnit::TestCaller<MathTest>( "testAdd",
* &MathTest::testAdd );
* test->run();
* \endcode
*
*
* The tests to be run can be collected into a TestSuite.
*
* \code
* public:
* static CppUnit::TestSuite *MathTest::suite () {
* CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite;
* suiteOfTests->addTest(new CppUnit::TestCaller<MathTest>(
* "testAdd", &MathTest::testAdd));
* suiteOfTests->addTest(new CppUnit::TestCaller<MathTest>(
* "testDivideByZero", &MathTest::testDivideByZero));
* return suiteOfTests;
* }
* \endcode
*
* A set of macros have been created for convenience. They are located in HelperMacros.h.
*
* \see TestResult, TestSuite, TestCaller,
* \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END,
* \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL.
*/
class CPPUNIT_API TestFixture
{
public:
virtual ~TestFixture() {};
//! \brief Set up context before running a test.
virtual void setUp() {};
//! Clean up after the test run.
virtual void tearDown() {};
};
CPPUNIT_NS_END
#endif

View File

@@ -0,0 +1,44 @@
#ifndef CPPUNIT_TESTLEAF_H
#define CPPUNIT_TESTLEAF_H
#include <cppunit/Test.h>
CPPUNIT_NS_BEGIN
/*! \brief A single test object.
*
* Base class for single test case: a test that doesn't have any children.
*
*/
class CPPUNIT_API TestLeaf: public Test
{
public:
/*! Returns 1 as the default number of test cases invoked by run().
*
* You may override this method when many test cases are invoked (RepeatedTest
* for example).
*
* \return 1.
* \see Test::countTestCases().
*/
int countTestCases() const;
/*! Returns the number of child of this test case: 0.
*
* You should never override this method: a TestLeaf as no children by definition.
*
* \return 0.
*/
int getChildTestCount() const;
/*! Always throws std::out_of_range.
* \see Test::doGetChildTestAt().
*/
Test *doGetChildTestAt( int index ) const;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTLEAF_H

View File

@@ -0,0 +1,148 @@
#ifndef CPPUNIT_TESTLISTENER_H // -*- C++ -*-
#define CPPUNIT_TESTLISTENER_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
class Exception;
class Test;
class TestFailure;
class TestResult;
/*! \brief Listener for test progress and result.
* \ingroup TrackingTestExecution
*
* Implementing the Observer pattern a TestListener may be registered
* to a TestResult to obtain information on the testing progress. Use
* specialized sub classes of TestListener for text output
* (TextTestProgressListener). Do not use the Listener for the test
* result output, use a subclass of Outputter instead.
*
* 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.
*
* Here is an example to track test time:
*
*
* \code
* #include <cppunit/TestListener.h>
* #include <cppunit/Test.h>
* #include <time.h> // for clock()
*
* class TimingListener : public CppUnit::TestListener
* {
* public:
* void startTest( CppUnit::Test *test )
* {
* _chronometer.start();
* }
*
* void endTest( CppUnit::Test *test )
* {
* _chronometer.end();
* addTest( test, _chronometer.elapsedTime() );
* }
*
* // ... (interface to add/read test timing result)
*
* private:
* Clock _chronometer;
* };
* \endcode
*
* And another example that track failure/success at test suite level and captures
* the TestPath of each suite:
* \code
* class SuiteTracker : public CppUnit::TestListener
* {
* public:
* void startSuite( CppUnit::Test *suite )
* {
* m_currentPath.add( suite );
* }
*
* void addFailure( const TestFailure &failure )
* {
* m_suiteFailure.top() = false;
* }
*
* void endSuite( CppUnit::Test *suite )
* {
* m_suiteStatus.insert( std::make_pair( suite, m_suiteFailure.top() ) );
* m_suitePaths.insert( std::make_pair( suite, m_currentPath ) );
*
* m_currentPath.up();
* m_suiteFailure.pop();
* }
*
* private:
* std::stack<bool> m_suiteFailure;
* CppUnit::TestPath m_currentPath;
* std::map<CppUnit::Test *, bool> m_suiteStatus;
* std::map<CppUnit::Test *, CppUnit::TestPath> m_suitePaths;
* };
* \endcode
*
* \see TestResult
*/
class CPPUNIT_API TestListener
{
public:
virtual ~TestListener() {}
/// Called when just before a TestCase is run.
virtual void startTest( Test * /*test*/ ) {}
/*! \brief 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*/ ) {}
/*! \brief Called by a TestComposite just before running its child tests.
*/
virtual void startSuite( Test * /*suite*/ ) {}
/*! \brief Called by a TestComposite after running its child tests.
*/
virtual void endSuite( Test * /*suite*/ ) {}
/*! \brief Called by a TestRunner before running the test.
*
* You can use this to do some global initialisation. A listener
* could also use to output a 'prolog' to the test run.
*
* \param test Test that is going to be run.
* \param eventManager Event manager used for the test run.
*/
virtual void startTestRun( Test * /*test*/,
TestResult * /*eventManager*/ ) {}
/*! \brief Called by a TestRunner after running the test.
*
* TextTestProgressListener use this to emit a line break. You can also use this
* to do some global uninitialisation.
*
* \param test Test that was run.
* \param eventManager Event manager used for the test run.
*/
virtual void endTestRun( Test * /*test*/,
TestResult * /*eventManager*/ ) {}
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTLISTENER_H

View File

@@ -0,0 +1,211 @@
#ifndef CPPUNIT_TESTPATH_H
#define CPPUNIT_TESTPATH_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/portability/CppUnitDeque.h>
#include <string>
CPPUNIT_NS_BEGIN
class Test;
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::deque<Test *>;
#endif
/*! \brief A List of Test representing a path to access a Test.
* \ingroup ExecutingTest
*
* The path can be converted to a string and resolved from a string with toString()
* and TestPath( Test *root, const std::string &pathAsString ).
*
* Pointed tests are not owned by the class.
*
* \see Test::resolvedTestPath()
*/
class CPPUNIT_API TestPath
{
public:
/*! \brief Constructs an invalid path.
*
* The path is invalid until a test is added with add().
*/
TestPath();
/*! \brief Constructs a valid path.
*
* \param root Test to add.
*/
TestPath( Test *root );
/*! \brief Constructs a path using a slice of another path.
* \param otherPath Path the test are copied from.
* \param indexFirst Zero based index of the first test to copy. Adjusted to be in valid
* range. \a count is adjusted with \a indexFirst.
* \param count Number of tests to copy. If < 0 then all test starting from index
* \a indexFirst are copied.
*/
TestPath( const TestPath &otherPath,
int indexFirst,
int count = -1 );
/*! \brief Resolves a path from a string returned by toString().
*
* If \a pathAsString is an absolute path (begins with '/'), then the first test name
* of the path must be the name of \a searchRoot. Otherwise, \a pathAsString is a
* relative path, and the first test found using Test::findTest() matching the first
* test name is used as root. An empty string resolve to a path containing
* \a searchRoot.
*
* The resolved path is always valid.
*
* \param searchRoot Test used to resolve the path.
* \param pathAsString String that contains the path as a string created by toString().
* \exception std::invalid_argument if one of the test names can not be resolved.
* \see toString().
*/
TestPath( Test *searchRoot,
const std::string &pathAsString );
/*! \brief Copy constructor.
* \param other Object to copy.
*/
TestPath( const TestPath &other );
virtual ~TestPath();
/*! \brief Tests if the path contains at least one test.
* \return \c true if the path contains at least one test, otherwise returns \c false.
*/
virtual bool isValid() const;
/*! \brief Adds a test to the path.
* \param test Pointer on the test to add. Must not be \c NULL.
*/
virtual void add( Test *test );
/*! \brief Adds all the tests of the specified path.
* \param path Path that contains the test to add.
*/
virtual void add( const TestPath &path );
/*! \brief Inserts a test at the specified index.
* \param test Pointer on the test to insert. Must not be \c NULL.
* \param index Zero based index indicating where the test is inserted.
* \exception std::out_of_range is \a index < 0 or \a index > getTestCount().
*/
virtual void insert( Test *test, int index );
/*! \brief Inserts all the tests at the specified path at a given index.
* \param path Path that contains the test to insert.
* \param index Zero based index indicating where the tests are inserted.
* \exception std::out_of_range is \a index < 0 or \a index > getTestCount(), and
* \a path is valid.
*/
virtual void insert( const TestPath &path, int index );
/*! \brief Removes all the test from the path.
*
* The path becomes invalid after this call.
*/
virtual void removeTests();
/*! \brief Removes the test at the specified index of the path.
* \param index Zero based index of the test to remove.
* \exception std::out_of_range is \a index < 0 or \a index >= getTestCount().
*/
virtual void removeTest( int index );
/*! \brief Removes the last test.
* \exception std::out_of_range is the path is invalid.
* \see isValid().
*/
virtual void up();
/*! \brief Returns the number of tests in the path.
* \return Number of tests in the path.
*/
virtual int getTestCount() const;
/*! \brief Returns the test of the specified index.
* \param index Zero based index of the test to return.
* \return Pointer on the test at index \a index. Never \c NULL.
* \exception std::out_of_range is \a index < 0 or \a index >= getTestCount().
*/
virtual Test *getTestAt( int index ) const;
/*! \brief Get the last test of the path.
* \return Pointer on the last test (test at the bottom of the hierarchy). Never \c NULL.
* \exception std::out_of_range if the path is not valid ( isValid() returns \c false ).
*/
virtual Test *getChildTest() const;
/*! \brief Returns the path as a string.
*
* For example, if a path is composed of three tests named "All Tests", "Math" and
* "Math::testAdd", toString() will return:
*
* "All Tests/Math/Math::testAdd".
*
* \return A string composed of the test names separated with a '/'. It is a relative
* path.
*/
virtual std::string toString() const;
/*! \brief Assignment operator.
* \param other Object to copy.
* \return This object.
*/
TestPath &operator =( const TestPath &other );
protected:
/*! \brief Checks that the specified test index is within valid range.
* \param index Zero based index to check.
* \exception std::out_of_range is \a index < 0 or \a index >= getTestCount().
*/
void checkIndexValid( int index ) const;
/// A list of test names.
typedef CppUnitDeque<std::string> PathTestNames;
/*! \brief Splits a path string into its test name components.
* \param pathAsString Path string created with toString().
* \param testNames Test name components are added to that container.
* \return \c true if the path is relative (does not begin with '/'), \c false
* if it is absolute (begin with '/').
*/
bool splitPathString( const std::string &pathAsString,
PathTestNames &testNames );
/*! \brief Finds the actual root of a path string and get the path string name components.
* \param searchRoot Test used as root if the path string is absolute, or to search
* the root test if the path string is relative.
* \param pathAsString Path string. May be absolute or relative.
* \param testNames Test name components are added to that container.
* \return Pointer on the resolved root test. Never \c NULL.
* \exception std::invalid_argument if either the root name can not be resolved or if
* pathAsString contains no name components.
*/
Test *findActualRoot( Test *searchRoot,
const std::string &pathAsString,
PathTestNames &testNames );
protected:
typedef CppUnitDeque<Test *> Tests;
Tests m_tests;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTPATH_H

View File

@@ -0,0 +1,156 @@
#ifndef CPPUNIT_TESTRESULT_H
#define CPPUNIT_TESTRESULT_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/SynchronizedObject.h>
#include <cppunit/portability/CppUnitDeque.h>
#include <string>
CPPUNIT_NS_BEGIN
class Exception;
class Functor;
class Protector;
class ProtectorChain;
class Test;
class TestFailure;
class TestListener;
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::deque<TestListener *>;
#endif
/*! \brief Manages TestListener.
* \ingroup TrackingTestExecution
*
* A single instance of this class is used when running the test. It is usually
* created by the test runner (TestRunner).
*
* This class shouldn't have to be inherited from. Use a TestListener
* or one of its subclasses to be informed of the ongoing tests.
* Use a Outputter to receive a test summary once it has finished
*
* TestResult supplies a template method 'setSynchronizationObject()'
* so that subclasses can provide mutual exclusion in the face of multiple
* threads. This can be useful when tests execute in one thread and
* they fill a subclass of TestResult which effects change in another
* thread. To have mutual exclusion, override setSynchronizationObject()
* and make sure that you create an instance of ExclusiveZone at the
* beginning of each method.
*
* \see Test, TestListener, TestResultCollector, Outputter.
*/
class CPPUNIT_API TestResult : protected SynchronizedObject
{
public:
/// Construct a TestResult
TestResult( SynchronizationObject *syncObject = 0 );
/// Destroys a test result
virtual ~TestResult();
virtual void addListener( TestListener *listener );
virtual void removeListener( TestListener *listener );
/// Resets the stop flag.
virtual void reset();
/// Stop testing
virtual void stop();
/// Returns whether testing should be stopped
virtual bool shouldStop() const;
/// Informs TestListener that a test will be started.
virtual void startTest( Test *test );
/*! \brief Adds an error to the list of errors.
* The passed in exception
* caused the error
*/
virtual void addError( Test *test, Exception *e );
/*! \brief Adds a failure to the list of failures. The passed in exception
* caused the failure.
*/
virtual void addFailure( Test *test, Exception *e );
/// Informs TestListener that a test was completed.
virtual void endTest( Test *test );
/// Informs TestListener that a test suite will be started.
virtual void startSuite( Test *test );
/// Informs TestListener that a test suite was completed.
virtual void endSuite( Test *test );
/*! \brief Run the specified test.
*
* Calls startTestRun(), test->run(this), and finally endTestRun().
*/
virtual void runTest( Test *test );
/*! \brief Protects a call to the specified functor.
*
* See Protector to understand how protector works. A default protector is
* always present. It captures CppUnit::Exception, std::exception and
* any other exceptions, retrieving as much as possible information about
* the exception as possible.
*
* Additional Protector can be added to the chain to support other exception
* types using pushProtector() and popProtector().
*
* \param functor Functor to call (typically a call to setUp(), runTest() or
* tearDown().
* \param test Test the functor is associated to (used for failure reporting).
* \param shortDescription Short description override for the failure message.
*/
virtual bool protect( const Functor &functor,
Test *test,
const std::string &shortDescription = std::string("") );
/// Adds the specified protector to the protector chain.
virtual void pushProtector( Protector *protector );
/// Removes the last protector from the protector chain.
virtual void popProtector();
protected:
/*! \brief Called to add a failure to the list of failures.
*/
void addFailure( const TestFailure &failure );
virtual void startTestRun( Test *test );
virtual void endTestRun( Test *test );
protected:
typedef CppUnitDeque<TestListener *> TestListeners;
TestListeners m_listeners;
ProtectorChain *m_protectorChain;
bool m_stop;
private:
TestResult( const TestResult &other );
TestResult &operator =( const TestResult &other );
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_TESTRESULT_H

View File

@@ -0,0 +1,87 @@
#ifndef CPPUNIT_TESTRESULTCOLLECTOR_H
#define CPPUNIT_TESTRESULTCOLLECTOR_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 4660 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/TestSuccessListener.h>
#include <cppunit/portability/CppUnitDeque.h>
CPPUNIT_NS_BEGIN
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::deque<TestFailure *>;
// template class CPPUNIT_API std::deque<Test *>;
#endif
/*! \brief Collects test result.
* \ingroup WritingTestResult
* \ingroup BrowsingCollectedTestResult
*
* 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.
* \see TestListener, TestFailure.
*/
class CPPUNIT_API TestResultCollector : public TestSuccessListener
{
public:
typedef CppUnitDeque<TestFailure *> TestFailures;
typedef CppUnitDeque<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:
void freeFailures();
Tests m_tests;
TestFailures m_failures;
int m_testErrors;
private:
/// Prevents the use of the copy constructor.
TestResultCollector( const TestResultCollector &copy );
/// Prevents the use of the copy operator.
void operator =( const TestResultCollector &copy );
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_TESTRESULTCOLLECTOR_H

View File

@@ -0,0 +1,135 @@
#ifndef CPPUNIT_TESTRUNNER_H
#define CPPUNIT_TESTRUNNER_H
#include <cppunit/TestSuite.h>
#include <string>
CPPUNIT_NS_BEGIN
class Test;
class TestResult;
/*! \brief Generic test runner.
* \ingroup ExecutingTest
*
* The TestRunner assumes ownership of all added tests: you can not add test
* or suite that are local variable since they can't be deleted.
*
* Example of usage:
* \code
* #include <cppunit/extensions/TestFactoryRegistry.h>
* #include <cppunit/CompilerOutputter.h>
* #include <cppunit/TestResult.h>
* #include <cppunit/TestResultCollector.h>
* #include <cppunit/TestRunner.h>
* #include <cppunit/TextTestProgressListener.h>
*
*
* int
* main( int argc, char* argv[] )
* {
* std::string testPath = (argc > 1) ? std::string(argv[1]) : "";
*
* // Create the event manager and test controller
* CppUnit::TestResult controller;
*
* // Add a listener that colllects test result
* CppUnit::TestResultCollector result;
* controller.addListener( &result );
*
* // Add a listener that print dots as test run.
* CppUnit::TextTestProgressListener progress;
* controller.addListener( &progress );
*
* // Add the top suite to the test runner
* CppUnit::TestRunner runner;
* runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
* try
* {
* std::cout << "Running " << testPath;
* runner.run( controller, testPath );
*
* std::cerr << std::endl;
*
* // Print test in a compiler compatible format.
* CppUnit::CompilerOutputter outputter( &result, std::cerr );
* outputter.write();
* }
* catch ( std::invalid_argument &e ) // Test path not resolved
* {
* std::cerr << std::endl
* << "ERROR: " << e.what()
* << std::endl;
* return 0;
* }
*
* return result.wasSuccessful() ? 0 : 1;
* }
* \endcode
*/
class CPPUNIT_API TestRunner
{
public:
/*! \brief Constructs a TestRunner object.
*/
TestRunner( );
/// Destructor.
virtual ~TestRunner();
/*! \brief Adds the specified test.
* \param test Test to add. The TestRunner takes ownership of the test.
*/
virtual void addTest( Test *test );
/*! \brief Runs a test using the specified controller.
* \param controller Event manager and controller used for testing
* \param testPath Test path string. See Test::resolveTestPath() for detail.
* \exception std::invalid_argument if no test matching \a testPath is found.
* see TestPath::TestPath( Test*, const std::string &)
* for detail.
*/
virtual void run( TestResult &controller,
const std::string &testPath = "" );
protected:
/*! \brief (INTERNAL) Mutating test suite.
*/
class CPPUNIT_API WrappingSuite : public TestSuite
{
public:
WrappingSuite( const std::string &name = "All Tests" );
int getChildTestCount() const;
std::string getName() const;
void run( TestResult *result );
protected:
Test *doGetChildTestAt( int index ) const;
bool hasOnlyOneTest() const;
Test *getUniqueChildTest() const;
};
protected:
WrappingSuite *m_suite;
private:
/// Prevents the use of the copy constructor.
TestRunner( const TestRunner &copy );
/// Prevents the use of the copy operator.
void operator =( const TestRunner &copy );
private:
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTRUNNER_H

View File

@@ -0,0 +1,39 @@
#ifndef CPPUNIT_TESTSUCCESSLISTENER_H
#define CPPUNIT_TESTSUCCESSLISTENER_H
#include <cppunit/SynchronizedObject.h>
#include <cppunit/TestListener.h>
CPPUNIT_NS_BEGIN
/*! \brief TestListener that checks if any test case failed.
* \ingroup TrackingTestExecution
*/
class CPPUNIT_API TestSuccessListener : public TestListener,
public SynchronizedObject
{
public:
/*! Constructs a TestSuccessListener object.
*/
TestSuccessListener( SynchronizationObject *syncObject = 0 );
/// Destructor.
virtual ~TestSuccessListener();
virtual void reset();
void addFailure( const TestFailure &failure );
/// Returns whether the entire test was successful or not.
virtual bool wasSuccessful() const;
private:
bool m_success;
};
CPPUNIT_NS_END
#endif // CPPUNIT_TESTSUCCESSLISTENER_H

View File

@@ -0,0 +1,80 @@
#ifndef CPPUNIT_TESTSUITE_H // -*- C++ -*-
#define CPPUNIT_TESTSUITE_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/TestComposite.h>
#include <cppunit/portability/CppUnitVector.h>
CPPUNIT_NS_BEGIN
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::vector<Test *>;
#endif
/*! \brief A Composite of Tests.
* \ingroup CreatingTestSuite
*
* It runs a collection of test cases. Here is an example.
* \code
* CppUnit::TestSuite *suite= new CppUnit::TestSuite();
* suite->addTest(new CppUnit::TestCaller<MathTest> (
* "testAdd", testAdd));
* suite->addTest(new CppUnit::TestCaller<MathTest> (
* "testDivideByZero", testDivideByZero));
* \endcode
* Note that \link TestSuite TestSuites \endlink assume lifetime
* control for any tests added to them.
*
* TestSuites do not register themselves in the TestRegistry.
* \see Test
* \see TestCaller
*/
class CPPUNIT_API TestSuite : public TestComposite
{
public:
/*! Constructs a test suite with the specified name.
*/
TestSuite( std::string name = "" );
~TestSuite();
/*! Adds the specified test to the suite.
* \param test Test to add. Must not be \c NULL.
*/
void addTest( Test *test );
/*! Returns the list of the tests (DEPRECATED).
* \deprecated Use getChildTestCount() & getChildTestAt() of the
* TestComposite interface instead.
* \return Reference on a vector that contains the tests of the suite.
*/
const CppUnitVector<Test *> &getTests() const;
/*! Destroys all the tests of the suite.
*/
virtual void deleteContents();
int getChildTestCount() const;
Test *doGetChildTestAt( int index ) const;
private:
CppUnitVector<Test *> m_tests;
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_TESTSUITE_H

View File

@@ -0,0 +1,59 @@
#ifndef CPPUNIT_TEXTOUTPUTTER_H
#define CPPUNIT_TEXTOUTPUTTER_H
#include <cppunit/Portability.h>
#include <cppunit/Outputter.h>
#include <cppunit/portability/Stream.h>
CPPUNIT_NS_BEGIN
class Exception;
class SourceLine;
class TestResultCollector;
class TestFailure;
/*! \brief Prints a TestResultCollector to a text stream.
* \ingroup WritingTestResult
*/
class CPPUNIT_API TextOutputter : public Outputter
{
public:
TextOutputter( TestResultCollector *result,
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;
OStream &m_stream;
private:
/// Prevents the use of the copy constructor.
TextOutputter( const TextOutputter &copy );
/// Prevents the use of the copy operator.
void operator =( const TextOutputter &copy );
};
CPPUNIT_NS_END
#endif // CPPUNIT_TEXTOUTPUTTER_H

View File

@@ -0,0 +1,44 @@
#ifndef CPPUNIT_TEXTTESTPROGRESSLISTENER_H
#define CPPUNIT_TEXTTESTPROGRESSLISTENER_H
#include <cppunit/TestListener.h>
CPPUNIT_NS_BEGIN
/*!
* \brief TestListener that show the status of each TestCase test result.
* \ingroup TrackingTestExecution
*/
class CPPUNIT_API TextTestProgressListener : public TestListener
{
public:
/*! Constructs a TextTestProgressListener object.
*/
TextTestProgressListener();
/// Destructor.
virtual ~TextTestProgressListener();
void startTest( Test *test );
void addFailure( const TestFailure &failure );
void endTestRun( Test *test,
TestResult *eventManager );
private:
/// Prevents the use of the copy constructor.
TextTestProgressListener( const TextTestProgressListener &copy );
/// Prevents the use of the copy operator.
void operator =( const TextTestProgressListener &copy );
private:
};
CPPUNIT_NS_END
#endif // CPPUNIT_TEXTTESTPROGRESSLISTENER_H

View File

@@ -0,0 +1,39 @@
#ifndef CPPUNIT_TEXTTESTRESULT_H
#define CPPUNIT_TEXTTESTRESULT_H
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/portability/Stream.h>
CPPUNIT_NS_BEGIN
class SourceLine;
class Exception;
class Test;
/*! \brief Holds printable test result (DEPRECATED).
* \ingroup TrackingTestExecution
*
* deprecated Use class TextTestProgressListener and TextOutputter instead.
*/
class CPPUNIT_API TextTestResult : public TestResult,
public TestResultCollector
{
public:
TextTestResult();
virtual void addFailure( const TestFailure &failure );
virtual void startTest( Test *test );
virtual void print( OStream &stream );
};
/** insertion operator for easy output */
CPPUNIT_API OStream &operator <<( OStream &stream,
TextTestResult &result );
CPPUNIT_NS_END
#endif // CPPUNIT_TEXTTESTRESULT_H

View File

@@ -0,0 +1,6 @@
#ifndef CPPUNIT_TEXTTESTRUNNER_H
#define CPPUNIT_TEXTTESTRUNNER_H
#include <cppunit/ui/text/TextTestRunner.h>
#endif // CPPUNIT_TEXTTESTRUNNER_H

View File

@@ -0,0 +1,167 @@
#ifndef CPPUNIT_XMLTESTRESULTOUTPUTTER_H
#define CPPUNIT_XMLTESTRESULTOUTPUTTER_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/Outputter.h>
#include <cppunit/portability/CppUnitDeque.h>
#include <cppunit/portability/CppUnitMap.h>
#include <cppunit/portability/Stream.h>
CPPUNIT_NS_BEGIN
class Test;
class TestFailure;
class TestResultCollector;
class XmlDocument;
class XmlElement;
class XmlOutputterHook;
/*! \brief Outputs a TestResultCollector in XML format.
* \ingroup WritingTestResult
*
* Save the test result as a XML stream.
*
* Additional datas can be added to the XML document using XmlOutputterHook.
* Hook are not owned by the XmlOutputter. They should be valid until
* destruction of the XmlOutputter. They can be removed with removeHook().
*
* \see XmlDocument, XmlElement, XmlOutputterHook.
*/
class CPPUNIT_API XmlOutputter : public Outputter
{
public:
/*! \brief Constructs a XmlOutputter object.
* \param result Result of the test run.
* \param stream Stream used to output the XML output.
* \param encoding Encoding used in the XML file (default is Latin-1).
*/
XmlOutputter( TestResultCollector *result,
OStream &stream,
std::string encoding = std::string("ISO-8859-1") );
/// Destructor.
virtual ~XmlOutputter();
/*! \brief Adds the specified hook to the outputter.
* \param hook Hook to add. Must not be \c NULL.
*/
virtual void addHook( XmlOutputterHook *hook );
/*! \brief Removes the specified hook from the outputter.
* \param hook Hook to remove.
*/
virtual void removeHook( XmlOutputterHook *hook );
/*! \brief Writes the specified result as an XML document to the stream.
*
* Refer to examples/cppunittest/XmlOutputterTest.cpp for example
* of use and XML document structure.
*/
virtual void write();
/*! \brief Sets the XSL style sheet used.
*
* \param styleSheet Name of the style sheet used. If empty, then no style sheet
* is used (default).
*/
virtual void setStyleSheet( const std::string &styleSheet );
/*! \brief set the output document as standalone or not.
*
* For the output document, specify wether it's a standalone XML
* document, or not.
*
* \param standalone if true, the output will be specified as standalone.
* if false, it will be not.
*/
virtual void setStandalone( bool standalone );
typedef CppUnitMap<Test *,TestFailure*, std::less<Test*> > FailedTests;
/*! \brief Sets the root element and adds its children.
*
* Set the root element of the XML Document and add its child elements.
*
* For all hooks, call beginDocument() just after creating the root element (it
* is empty at this time), and endDocument() once all the datas have been added
* to the root element.
*/
virtual void setRootNode();
virtual void addFailedTests( FailedTests &failedTests,
XmlElement *rootNode );
virtual void addSuccessfulTests( FailedTests &failedTests,
XmlElement *rootNode );
/*! \brief Adds the statics element to the root node.
*
* Creates a new element containing statistics data and adds it to the root element.
* Then, for all hooks, call statisticsAdded().
* \param rootNode Root element.
*/
virtual void addStatistics( XmlElement *rootNode );
/*! \brief Adds a failed test to the failed tests node.
* Creates a new element containing datas about the failed test, and adds it to
* the failed tests element.
* Then, for all hooks, call failTestAdded().
*/
virtual void addFailedTest( Test *test,
TestFailure *failure,
int testNumber,
XmlElement *testsNode );
virtual void addFailureLocation( TestFailure *failure,
XmlElement *testElement );
/*! \brief Adds a successful test to the successful tests node.
* Creates a new element containing datas about the successful test, and adds it to
* the successful tests element.
* Then, for all hooks, call successfulTestAdded().
*/
virtual void addSuccessfulTest( Test *test,
int testNumber,
XmlElement *testsNode );
protected:
virtual void fillFailedTestsMap( FailedTests &failedTests );
protected:
typedef CppUnitDeque<XmlOutputterHook *> Hooks;
TestResultCollector *m_result;
OStream &m_stream;
std::string m_encoding;
std::string m_styleSheet;
XmlDocument *m_xml;
Hooks m_hooks;
private:
/// Prevents the use of the copy constructor.
XmlOutputter( const XmlOutputter &copy );
/// Prevents the use of the copy operator.
void operator =( const XmlOutputter &copy );
private:
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_XMLTESTRESULTOUTPUTTER_H

View File

@@ -0,0 +1,163 @@
#ifndef CPPUNIT_XMLOUTPUTTERHOOK_H
#define CPPUNIT_XMLOUTPUTTERHOOK_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
class Test;
class TestFailure;
class XmlDocument;
class XmlElement;
/*! \brief Hook to customize Xml output.
*
* XmlOutputterHook can be passed to XmlOutputter to customize the XmlDocument.
*
* Common customizations are:
* - adding some datas to successfull or failed test with
* failTestAdded() and successfulTestAdded(),
* - adding some statistics with statisticsAdded(),
* - adding other datas with beginDocument() or endDocument().
*
* See examples/ClockerPlugIn which makes use of most the hook.
*
* Another simple example of an outputter hook is shown below. It may be
* used to add some meta information to your result files. In the example,
* the author name as well as the project name and test creation date is
* added to the head of the xml file.
*
* In order to make this information stored within the xml file, the virtual
* member function beginDocument() is overriden where a new
* XmlElement object is created.
*
* This element is simply added to the root node of the document which
* makes the information automatically being stored when the xml file
* is written.
*
* \code
* #include <cppunit/XmlOutputterHook.h>
* #include <cppunit/XmlElement.h>
* #include <cppunit/tools/StringTools.h>
*
* ...
*
* class MyXmlOutputterHook : public CppUnit::XmlOutputterHook
* {
* public:
* MyXmlOutputterHook(const std::string projectName,
* const std::string author)
* {
* m_projectName = projectName;
* m_author = author;
* };
*
* virtual ~MyXmlOutputterHook()
* {
* };
*
* void beginDocument(CppUnit::XmlDocument* document)
* {
* if (!document)
* return;
*
* // dump current time
* std::string szDate = CppUnit::StringTools::toString( (int)time(0) );
* CppUnit::XmlElement* metaEl = new CppUnit::XmlElement("SuiteInfo",
* "");
*
* metaEl->addElement( new CppUnit::XmlElement("Author", m_author) );
* metaEl->addElement( new CppUnit::XmlElement("Project", m_projectName) );
* metaEl->addElement( new CppUnit::XmlElement("Date", szDate ) );
*
* document->rootElement().addElement(metaEl);
* };
* private:
* std::string m_projectName;
* std::string m_author;
* };
* \endcode
*
* Within your application's main code, you need to snap the hook
* object into your xml outputter object like shown below:
*
* \code
* CppUnit::TextUi::TestRunner runner;
* std::ofstream outputFile("testResults.xml");
*
* CppUnit::XmlOutputter* outputter = new CppUnit::XmlOutputter( &runner.result(),
* outputFile );
* MyXmlOutputterHook hook("myProject", "meAuthor");
* outputter->addHook(&hook);
* runner.setOutputter(outputter);
* runner.addTest( VectorFixture::suite() );
* runner.run();
* outputFile.close();
* \endcode
*
* This results into the following output:
*
* \code
* <TestRun>
* <suiteInfo>
* <author>meAuthor</author>
* <project>myProject</project>
* <date>1028143912</date>
* </suiteInfo>
* <FailedTests>
* ...
* \endcode
*
* \see XmlOutputter, CppUnitTestPlugIn.
*/
class CPPUNIT_API XmlOutputterHook
{
public:
/*! Called before any elements is added to the root element.
* \param document XML Document being created.
*/
virtual void beginDocument( XmlDocument *document );
/*! Called after adding all elements to the root element.
* \param document XML Document being created.
*/
virtual void endDocument( XmlDocument *document );
/*! Called after adding a fail test element.
* \param document XML Document being created.
* \param testElement \<FailedTest\> element.
* \param test Test that failed.
* \param failure Test failure data.
*/
virtual void failTestAdded( XmlDocument *document,
XmlElement *testElement,
Test *test,
TestFailure *failure );
/*! Called after adding a successful test element.
* \param document XML Document being created.
* \param testElement \<Test\> element.
* \param test Test that was successful.
*/
virtual void successfulTestAdded( XmlDocument *document,
XmlElement *testElement,
Test *test );
/*! Called after adding the statistic element.
* \param document XML Document being created.
* \param statisticsElement \<Statistics\> element.
*/
virtual void statisticsAdded( XmlDocument *document,
XmlElement *statisticsElement );
virtual ~XmlOutputterHook() {}
};
CPPUNIT_NS_END
#endif // CPPUNIT_XMLOUTPUTTERHOOK_H

View File

@@ -0,0 +1,33 @@
#ifndef CPPUNIT_CONFIG_CPPUNITAPI
#define CPPUNIT_CONFIG_CPPUNITAPI
#undef CPPUNIT_API
#ifdef WIN32
// define CPPUNIT_DLL_BUILD when building CppUnit dll.
#ifdef CPPUNIT_BUILD_DLL
#define CPPUNIT_API __declspec(dllexport)
#endif
// define CPPUNIT_DLL when linking to CppUnit dll.
#ifdef CPPUNIT_DLL
#define CPPUNIT_API __declspec(dllimport)
#endif
#ifdef CPPUNIT_API
#undef CPPUNIT_NEED_DLL_DECL
#define CPPUNIT_NEED_DLL_DECL 1
#endif
#endif
#ifndef CPPUNIT_API
#define CPPUNIT_API
#undef CPPUNIT_NEED_DLL_DECL
#define CPPUNIT_NEED_DLL_DECL 0
#endif
#endif // CPPUNIT_CONFIG_CPPUNITAPI

View File

@@ -0,0 +1,76 @@
#ifndef CPPUNIT_CONFIG_SELECTDLLLOADER_H
#define CPPUNIT_CONFIG_SELECTDLLLOADER_H
/*! \file
* Selects DynamicLibraryManager implementation.
*
* Don't include this file directly. Include Portability.h instead.
*/
/*!
* \def CPPUNIT_NO_TESTPLUGIN
* \brief If defined, then plug-in related classes and functions will not be compiled.
*
* \internal
* CPPUNIT_HAVE_WIN32_DLL_LOADER
* If defined, Win32 implementation of DynamicLibraryManager will be used.
*
* CPPUNIT_HAVE_BEOS_DLL_LOADER
* If defined, BeOs implementation of DynamicLibraryManager will be used.
*
* CPPUNIT_HAVE_UNIX_DLL_LOADER
* If defined, Unix implementation (dlfcn.h) of DynamicLibraryManager will be used.
*/
/*!
* \def CPPUNIT_PLUGIN_EXPORT
* \ingroup WritingTestPlugIn
* \brief A macro to export a function from a dynamic library
*
* This macro export the C function following it from a dynamic library.
* Exporting the function makes it accessible to the DynamicLibraryManager.
*
* Example of usage:
* \code
* #include <cppunit/include/plugin/TestPlugIn.h>
*
* CPPUNIT_PLUGIN_EXPORT CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void)
* {
* ...
* return &myPlugInInterface;
* }
* \endcode
*/
#if !defined(CPPUNIT_NO_TESTPLUGIN)
// Is WIN32 platform ?
#if defined(WIN32)
#define CPPUNIT_HAVE_WIN32_DLL_LOADER 1
#undef CPPUNIT_PLUGIN_EXPORT
#define CPPUNIT_PLUGIN_EXPORT extern "C" __declspec(dllexport)
// Is BeOS platform ?
#elif defined(__BEOS__)
#define CPPUNIT_HAVE_BEOS_DLL_LOADER 1
// Is Unix platform and have shl_load() (hp-ux)
#elif defined(CPPUNIT_HAVE_SHL_LOAD)
#define CPPUNIT_HAVE_UNIX_SHL_LOADER 1
// Is Unix platform and have include <dlfcn.h>
#elif defined(CPPUNIT_HAVE_LIBDL)
#define CPPUNIT_HAVE_UNIX_DLL_LOADER 1
// Otherwise, disable support for DllLoader
#else
#define CPPUNIT_NO_TESTPLUGIN 1
#endif
#if !defined(CPPUNIT_PLUGIN_EXPORT)
#define CPPUNIT_PLUGIN_EXPORT extern "C"
#endif // !defined(CPPUNIT_PLUGIN_EXPORT)
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_CONFIG_SELECTDLLLOADER_H

View File

@@ -0,0 +1,14 @@
#ifndef CPPUNIT_CONFIG_H_INCLUDED
#define CPPUNIT_CONFIG_H_INCLUDED
#include <cppunit/Portability.h>
#ifdef _MSC_VER
#pragma warning(disable: 4018 4284 4146)
#if _MSC_VER >= 1400
#pragma warning(disable: 4996) // sprintf is deprecated
#endif
#endif
#endif // CPPUNIT_CONFIG_H_INCLUDED

View File

@@ -0,0 +1,47 @@
#ifndef _INCLUDE_CPPUNIT_CONFIG_BCB5_H
#define _INCLUDE_CPPUNIT_CONFIG_BCB5_H 1
#define HAVE_CMATH 1
/* include/cppunit/config-bcb5.h. Manually adapted from
include/cppunit/config-auto.h */
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if library uses std::string::compare(string,pos,n) */
#ifndef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#define CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST 0
#endif
/* Define if you have the <dlfcn.h> header file. */
#ifdef CPPUNIT_HAVE_DLFCN_H
#undef CPPUNIT_HAVE_DLFCN_H
#endif
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if the compiler supports Run-Time Type Identification */
#ifndef CPPUNIT_HAVE_RTTI
#define CPPUNIT_HAVE_RTTI 1
#endif
/* Define to 1 to use type_info::name() for class names */
#ifndef CPPUNIT_USE_TYPEINFO_NAME
#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI
#endif
#define CPPUNIT_HAVE_SSTREAM 1
/* Name of package */
#ifndef CPPUNIT_PACKAGE
#define CPPUNIT_PACKAGE "cppunit"
#endif
/* _INCLUDE_CPPUNIT_CONFIG_BCB5_H */
#endif

View File

@@ -0,0 +1,78 @@
#ifndef _INCLUDE_CPPUNIT_CONFIG_EVC4_H
#define _INCLUDE_CPPUNIT_CONFIG_EVC4_H 1
#if _MSC_VER > 1000 // VC++
#pragma warning( disable : 4786 ) // disable warning debug symbol > 255...
#endif // _MSC_VER > 1000
#define HAVE_CMATH 1
/* include/cppunit/config-msvc6.h. Manually adapted from
include/cppunit/config-auto.h */
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if library uses std::string::compare(string,pos,n) */
#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#endif
/* Define if you have the <dlfcn.h> header file. */
#ifdef CPPUNIT_HAVE_DLFCN_H
#undef CPPUNIT_HAVE_DLFCN_H
#endif
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if the compiler supports Run-Time Type Identification */
#ifndef CPPUNIT_HAVE_RTTI
#define CPPUNIT_HAVE_RTTI 0
#endif
/* Define to 1 to use type_info::name() for class names */
#ifndef CPPUNIT_USE_TYPEINFO_NAME
#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI
#endif
#define CPPUNIT_NO_STREAM 1
#define CPPUNIT_NO_ASSERT 1
#define CPPUNIT_HAVE_SSTREAM 0
/* Name of package */
#ifndef CPPUNIT_PACKAGE
#define CPPUNIT_PACKAGE "cppunit"
#endif
// Compiler error location format for CompilerOutputter
// See class CompilerOutputter for format.
#undef CPPUNIT_COMPILER_LOCATION_FORMAT
#if _MSC_VER >= 1300 // VS 7.0
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l) : error : "
#else
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l):"
#endif
/* define to 1 if the compiler has _finite() */
#ifndef CPPUNIT_HAVE__FINITE
#define CPPUNIT_HAVE__FINITE 1
#endif
// Uncomment to turn on STL wrapping => use this to test compilation.
// This will make CppUnit subclass std::vector & co to provide default
// parameter.
/*#define CPPUNIT_STD_NEED_ALLOCATOR 1
#define CPPUNIT_STD_ALLOCATOR std::allocator<T>
//#define CPPUNIT_NO_NAMESPACE 1
*/
/* _INCLUDE_CPPUNIT_CONFIG_EVC4_H */
#endif

View File

@@ -0,0 +1,58 @@
#ifndef _INCLUDE_CPPUNIT_CONFIG_MAC_H
#define _INCLUDE_CPPUNIT_CONFIG_MAC_H 1
/* MacOS X should be installed using the configure script.
This file is for other macs.
It is not integrated into <cppunit/Portability.h> because we don't
know a suitable preprocessor symbol that will distinguish MacOS X
from other MacOS versions. Email us if you know the answer.
*/
/* define if library uses std::string::compare(string,pos,n) */
#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#endif
/* define if the library defines strstream */
#ifndef CPPUNIT_HAVE_CLASS_STRSTREAM
#define CPPUNIT_HAVE_CLASS_STRSTREAM 1
#endif
/* Define if you have the <cmath> header file. */
#ifdef CPPUNIT_HAVE_CMATH
#undef CPPUNIT_HAVE_CMATH
#endif
/* Define if you have the <dlfcn.h> header file. */
#ifdef CPPUNIT_HAVE_DLFCN_H
#undef CPPUNIT_HAVE_DLFCN_H
#endif
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if the compiler supports Run-Time Type Identification */
#ifndef CPPUNIT_HAVE_RTTI
#define CPPUNIT_HAVE_RTTI 1
#endif
/* define if the compiler has stringstream */
#ifndef CPPUNIT_HAVE_SSTREAM
#define CPPUNIT_HAVE_SSTREAM 1
#endif
/* Define if you have the <strstream> header file. */
#ifndef CPPUNIT_HAVE_STRSTREAM
#define CPPUNIT_HAVE_STRSTREAM 1
#endif
/* Define to 1 to use type_info::name() for class names */
#ifndef CPPUNIT_USE_TYPEINFO_NAME
#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI
#endif
/* _INCLUDE_CPPUNIT_CONFIG_MAC_H */
#endif

View File

@@ -0,0 +1,86 @@
#ifndef _INCLUDE_CPPUNIT_CONFIG_MSVC6_H
#define _INCLUDE_CPPUNIT_CONFIG_MSVC6_H 1
#if _MSC_VER > 1000 // VC++
#pragma warning( disable : 4786 ) // disable warning debug symbol > 255...
#endif // _MSC_VER > 1000
#define HAVE_CMATH 1
/* include/cppunit/config-msvc6.h. Manually adapted from
include/cppunit/config-auto.h */
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if library uses std::string::compare(string,pos,n) */
#ifdef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#undef CPPUNIT_FUNC_STRING_COMPARE_STRING_FIRST
#endif
/* Define if you have the <dlfcn.h> header file. */
#ifdef CPPUNIT_HAVE_DLFCN_H
#undef CPPUNIT_HAVE_DLFCN_H
#endif
/* define to 1 if the compiler implements namespaces */
#ifndef CPPUNIT_HAVE_NAMESPACES
#define CPPUNIT_HAVE_NAMESPACES 1
#endif
/* define if the compiler supports Run-Time Type Identification */
#ifndef CPPUNIT_HAVE_RTTI
# ifdef _CPPRTTI // Defined by the compiler option /GR
# define CPPUNIT_HAVE_RTTI 1
# else
# define CPPUNIT_HAVE_RTTI 0
# endif
#endif
/* Define to 1 to use type_info::name() for class names */
#ifndef CPPUNIT_USE_TYPEINFO_NAME
#define CPPUNIT_USE_TYPEINFO_NAME CPPUNIT_HAVE_RTTI
#endif
#define CPPUNIT_HAVE_SSTREAM 1
/* Name of package */
#ifndef CPPUNIT_PACKAGE
#define CPPUNIT_PACKAGE "cppunit"
#endif
// Compiler error location format for CompilerOutputter
// See class CompilerOutputter for format.
#undef CPPUNIT_COMPILER_LOCATION_FORMAT
#if _MSC_VER >= 1300 // VS 7.0
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l) : error : "
#else
# define CPPUNIT_COMPILER_LOCATION_FORMAT "%p(%l):"
#endif
// Define to 1 if the compiler support C++ style cast.
#define CPPUNIT_HAVE_CPP_CAST 1
/* define to 1 if the compiler has _finite() */
#ifndef CPPUNIT_HAVE__FINITE
#define CPPUNIT_HAVE__FINITE 1
#endif
// Uncomment to turn on STL wrapping => use this to test compilation.
// This will make CppUnit subclass std::vector & co to provide default
// parameter.
/*#define CPPUNIT_STD_NEED_ALLOCATOR 1
#define CPPUNIT_STD_ALLOCATOR std::allocator<T>
//#define CPPUNIT_NO_NAMESPACE 1
*/
#if _MSC_VER >= 1300 // VS 7.0
#define CPPUNIT_UNIQUE_COUNTER __COUNTER__
#endif // if _MSC_VER >= 1300 // VS 7.0
/* _INCLUDE_CPPUNIT_CONFIG_MSVC6_H */
#endif

View File

@@ -0,0 +1,83 @@
#ifndef CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H
#define CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H
#include <cppunit/extensions/TestSuiteFactory.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <string>
CPPUNIT_NS_BEGIN
/*! \brief (Implementation) Automatically register the test suite of the specified type.
*
* You should not use this class directly. Instead, use the following macros:
* - CPPUNIT_TEST_SUITE_REGISTRATION()
* - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION()
*
* This object will register the test returned by TestCaseType::suite()
* when constructed to the test registry.
*
* This object is intented to be used as a static variable.
*
*
* \param TestCaseType Type of the test case which suite is registered.
* \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
* \see CppUnit::TestFactoryRegistry.
*/
template<class TestCaseType>
class AutoRegisterSuite
{
public:
/** Auto-register the suite factory in the global registry.
*/
AutoRegisterSuite()
: m_registry( &TestFactoryRegistry::getRegistry() )
{
m_registry->registerFactory( &m_factory );
}
/** Auto-register the suite factory in the specified registry.
* \param name Name of the registry.
*/
AutoRegisterSuite( const std::string &name )
: m_registry( &TestFactoryRegistry::getRegistry( name ) )
{
m_registry->registerFactory( &m_factory );
}
~AutoRegisterSuite()
{
if ( TestFactoryRegistry::isValid() )
m_registry->unregisterFactory( &m_factory );
}
private:
TestFactoryRegistry *m_registry;
TestSuiteFactory<TestCaseType> m_factory;
};
/*! \brief (Implementation) Automatically adds a registry into another registry.
*
* Don't use this class. Use the macros CPPUNIT_REGISTRY_ADD() and
* CPPUNIT_REGISTRY_ADD_TO_DEFAULT() instead.
*/
class AutoRegisterRegistry
{
public:
AutoRegisterRegistry( const std::string &which,
const std::string &to )
{
TestFactoryRegistry::getRegistry( to ).addRegistry( which );
}
AutoRegisterRegistry( const std::string &which )
{
TestFactoryRegistry::getRegistry().addRegistry( which );
}
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H

View File

@@ -0,0 +1,104 @@
#ifndef CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H
#define CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H
#include <cppunit/Portability.h>
#include <cppunit/Exception.h>
#include <cppunit/extensions/TestCaseDecorator.h>
CPPUNIT_NS_BEGIN
/*! \brief Expected exception test case decorator.
*
* A decorator used to assert that a specific test case should throw an
* exception of a given type.
*
* You should use this class only if you need to check the exception object
* state (that a specific cause is set for example). If you don't need to
* do that, you might consider using CPPUNIT_TEST_EXCEPTION() instead.
*
* Intended use is to subclass and override checkException(). Example:
*
* \code
*
* class NetworkErrorTestCaseDecorator :
* public ExceptionTestCaseDecorator<NetworkError>
* {
* public:
* NetworkErrorTestCaseDecorator( NetworkError::Cause expectedCause )
* : m_expectedCause( expectedCause )
* {
* }
* private:
* void checkException( ExpectedExceptionType &e )
* {
* CPPUNIT_ASSERT_EQUAL( m_expectedCause, e.getCause() );
* }
*
* NetworkError::Cause m_expectedCause;
* };
* \endcode
*
*/
template<class ExpectedException>
class ExceptionTestCaseDecorator : public TestCaseDecorator
{
public:
typedef ExpectedException ExpectedExceptionType;
/*! \brief Decorates the specified test.
* \param test TestCase to decorate. Assumes ownership of the test.
*/
ExceptionTestCaseDecorator( TestCase *test )
: TestCaseDecorator( test )
{
}
/*! \brief Checks that the expected exception is thrown by the decorated test.
* is thrown.
*
* Calls the decorated test runTest() and checks that an exception of
* type ExpectedException is thrown. Call checkException() passing the
* exception that was caught so that some assertions can be made if
* needed.
*/
void runTest()
{
try
{
TestCaseDecorator::runTest();
}
catch ( ExpectedExceptionType &e )
{
checkException( e );
return;
}
// Moved outside the try{} statement to handle the case where the
// expected exception type is Exception (expecting assertion failure).
#if CPPUNIT_USE_TYPEINFO_NAME
throw Exception( Message(
"expected exception not thrown",
"Expected exception type: " +
TypeInfoHelper::getClassName(
typeid( ExpectedExceptionType ) ) ) );
#else
throw Exception( Message("expected exception not thrown") );
#endif
}
private:
/*! \brief Called when the exception is caught.
*
* Should be overriden to check the exception.
*/
virtual void checkException( ExpectedExceptionType & )
{
}
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_EXCEPTIONTESTCASEDECORATOR_H

View File

@@ -0,0 +1,541 @@
// //////////////////////////////////////////////////////////////////////////
// Header file HelperMacros.h
// (c)Copyright 2000, Baptiste Lepilleur.
// Created: 2001/04/15
// //////////////////////////////////////////////////////////////////////////
#ifndef CPPUNIT_EXTENSIONS_HELPERMACROS_H
#define CPPUNIT_EXTENSIONS_HELPERMACROS_H
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
#include <cppunit/extensions/AutoRegisterSuite.h>
#include <cppunit/extensions/ExceptionTestCaseDecorator.h>
#include <cppunit/extensions/TestFixtureFactory.h>
#include <cppunit/extensions/TestNamer.h>
#include <cppunit/extensions/TestSuiteBuilderContext.h>
#include <memory>
/*! \addtogroup WritingTestFixture Writing test fixture
*/
/** @{
*/
/** \file
* Macros intended to ease the definition of test suites.
*
* The macros
* CPPUNIT_TEST_SUITE(), CPPUNIT_TEST(), and CPPUNIT_TEST_SUITE_END()
* are designed to facilitate easy creation of a test suite.
* For example,
*
* \code
* #include <cppunit/extensions/HelperMacros.h>
* class MyTest : public CppUnit::TestFixture {
* CPPUNIT_TEST_SUITE( MyTest );
* CPPUNIT_TEST( testEquality );
* CPPUNIT_TEST( testSetName );
* CPPUNIT_TEST_SUITE_END();
* public:
* void testEquality();
* void testSetName();
* };
* \endcode
*
* The effect of these macros is to define two methods in the
* class MyTest. The first method is an auxiliary function
* named registerTests that you will not need to call directly.
* The second function
* \code static CppUnit::TestSuite *suite()\endcode
* returns a pointer to the suite of tests defined by the CPPUNIT_TEST()
* macros.
*
* Rather than invoking suite() directly,
* the macro CPPUNIT_TEST_SUITE_REGISTRATION() is
* used to create a static variable that automatically
* registers its test suite in a global registry.
* The registry yields a Test instance containing all the
* registered suites.
* \code
* CPPUNIT_TEST_SUITE_REGISTRATION( MyTest );
* CppUnit::Test* tp =
* CppUnit::TestFactoryRegistry::getRegistry().makeTest();
* \endcode
*
* The test suite macros can even be used with templated test classes.
* For example:
*
* \code
* template<typename CharType>
* class StringTest : public CppUnit::TestFixture {
* CPPUNIT_TEST_SUITE( StringTest );
* CPPUNIT_TEST( testAppend );
* CPPUNIT_TEST_SUITE_END();
* public:
* ...
* };
* \endcode
*
* You need to add in an implementation file:
*
* \code
* CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<char> );
* CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<wchar_t> );
* \endcode
*/
/*! \brief Begin test suite
*
* This macro starts the declaration of a new test suite.
* Use CPPUNIT_TEST_SUB_SUITE() instead, if you wish to include the
* test suite of the parent class.
*
* \param ATestFixtureType Type of the test case class. This type \b MUST
* be derived from TestFixture.
* \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END,
* \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL.
*/
#define CPPUNIT_TEST_SUITE( ATestFixtureType ) \
public: \
typedef ATestFixtureType TestFixtureType; \
\
private: \
static const CPPUNIT_NS::TestNamer &getTestNamer__() \
{ \
static CPPUNIT_TESTNAMER_DECL( testNamer, ATestFixtureType ); \
return testNamer; \
} \
\
public: \
typedef CPPUNIT_NS::TestSuiteBuilderContext<TestFixtureType> \
TestSuiteBuilderContextType; \
\
static void \
addTestsToSuite( CPPUNIT_NS::TestSuiteBuilderContextBase &baseContext ) \
{ \
TestSuiteBuilderContextType context( baseContext )
/*! \brief Begin test suite (includes parent suite)
*
* This macro may only be used in a class whose parent class
* defines a test suite using CPPUNIT_TEST_SUITE() or CPPUNIT_TEST_SUB_SUITE().
*
* This macro begins the declaration of a test suite, in the same
* manner as CPPUNIT_TEST_SUITE(). In addition, the test suite of the
* parent is automatically inserted in the test suite being
* defined.
*
* Here is an example:
*
* \code
* #include <cppunit/extensions/HelperMacros.h>
* class MySubTest : public MyTest {
* CPPUNIT_TEST_SUB_SUITE( MySubTest, MyTest );
* CPPUNIT_TEST( testAdd );
* CPPUNIT_TEST( testSub );
* CPPUNIT_TEST_SUITE_END();
* public:
* void testAdd();
* void testSub();
* };
* \endcode
*
* \param ATestFixtureType Type of the test case class. This type \b MUST
* be derived from TestFixture.
* \param ASuperClass Type of the parent class.
* \see CPPUNIT_TEST_SUITE.
*/
#define CPPUNIT_TEST_SUB_SUITE( ATestFixtureType, ASuperClass ) \
public: \
typedef ASuperClass ParentTestFixtureType; \
private: \
CPPUNIT_TEST_SUITE( ATestFixtureType ); \
ParentTestFixtureType::addTestsToSuite( baseContext )
/*! \brief End declaration of the test suite.
*
* After this macro, member access is set to "private".
*
* \see CPPUNIT_TEST_SUITE.
* \see CPPUNIT_TEST_SUITE_REGISTRATION.
*/
#define CPPUNIT_TEST_SUITE_END() \
} \
\
static CPPUNIT_NS::TestSuite *suite() \
{ \
const CPPUNIT_NS::TestNamer &namer = getTestNamer__(); \
std::auto_ptr<CPPUNIT_NS::TestSuite> suite( \
new CPPUNIT_NS::TestSuite( namer.getFixtureName() )); \
CPPUNIT_NS::ConcretTestFixtureFactory<TestFixtureType> factory; \
CPPUNIT_NS::TestSuiteBuilderContextBase context( *suite.get(), \
namer, \
factory ); \
TestFixtureType::addTestsToSuite( context ); \
return suite.release(); \
} \
private: /* dummy typedef so that the macro can still end with ';'*/ \
typedef int CppUnitDummyTypedefForSemiColonEnding__
/*! \brief End declaration of an abstract test suite.
*
* Use this macro to indicate that the %TestFixture is abstract. No
* static suite() method will be declared.
*
* After this macro, member access is set to "private".
*
* Here is an example of usage:
*
* The abstract test fixture:
* \code
* #include <cppunit/extensions/HelperMacros.h>
* class AbstractDocument;
* class AbstractDocumentTest : public CppUnit::TestFixture {
* CPPUNIT_TEST_SUITE( AbstractDocumentTest );
* CPPUNIT_TEST( testInsertText );
* CPPUNIT_TEST_SUITE_END_ABSTRACT();
* public:
* void testInsertText();
*
* void setUp()
* {
* m_document = makeDocument();
* }
*
* void tearDown()
* {
* delete m_document;
* }
* protected:
* virtual AbstractDocument *makeDocument() =0;
*
* AbstractDocument *m_document;
* };\endcode
*
* The concret test fixture:
* \code
* class RichTextDocumentTest : public AbstractDocumentTest {
* CPPUNIT_TEST_SUB_SUITE( RichTextDocumentTest, AbstractDocumentTest );
* CPPUNIT_TEST( testInsertFormatedText );
* CPPUNIT_TEST_SUITE_END();
* public:
* void testInsertFormatedText();
* protected:
* AbstractDocument *makeDocument()
* {
* return new RichTextDocument();
* }
* };\endcode
*
* \see CPPUNIT_TEST_SUB_SUITE.
* \see CPPUNIT_TEST_SUITE_REGISTRATION.
*/
#define CPPUNIT_TEST_SUITE_END_ABSTRACT() \
} \
private: /* dummy typedef so that the macro can still end with ';'*/ \
typedef int CppUnitDummyTypedefForSemiColonEnding__
/*! \brief Add a test to the suite (for custom test macro).
*
* The specified test will be added to the test suite being declared. This macro
* is intended for \e advanced usage, to extend %CppUnit by creating new macro such
* as CPPUNIT_TEST_EXCEPTION()...
*
* Between macro CPPUNIT_TEST_SUITE() and CPPUNIT_TEST_SUITE_END(), you can assume
* that the following variables can be used:
* \code
* typedef TestSuiteBuilder<TestFixtureType> TestSuiteBuilderType;
* TestSuiteBuilderType &context;
* \endcode
*
* \c context can be used to name test case, create new test fixture instance,
* or add test case to the test fixture suite.
*
* Below is an example that show how to use this macro to create new macro to add
* test to the fixture suite. The macro below show how you would add a new type
* of test case which fails if the execution last more than a given time limit.
* It relies on an imaginary TimeOutTestCaller class which has an interface similar
* to TestCaller.
*
* \code
* #define CPPUNITEX_TEST_TIMELIMIT( testMethod, timeLimit ) \
* CPPUNIT_TEST_SUITE_ADD_TEST( (new TimeOutTestCaller<TestFixtureType>( \
* namer.getTestNameFor( #testMethod ), \
* &TestFixtureType::testMethod, \
* factory.makeFixture(), \
* timeLimit ) ) )
*
* class PerformanceTest : CppUnit::TestFixture
* {
* public:
* CPPUNIT_TEST_SUITE( PerformanceTest );
* CPPUNITEX_TEST_TIMELIMIT( testSortReverseOrder, 5.0 );
* CPPUNIT_TEST_SUITE_END();
*
* void testSortReverseOrder();
* };
* \endcode
*
* \param test Test to add to the suite. Must be a subclass of Test. The test name
* should have been obtained using TestNamer::getTestNameFor().
*/
#define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \
context.addTest( test )
/*! \brief Add a method to the suite.
* \param testMethod Name of the method of the test case to add to the
* suite. The signature of the method must be of
* type: void testMethod();
* \see CPPUNIT_TEST_SUITE.
*/
#define CPPUNIT_TEST( testMethod ) \
CPPUNIT_TEST_SUITE_ADD_TEST( \
( new CPPUNIT_NS::TestCaller<TestFixtureType>( \
context.getTestNameFor( #testMethod), \
&TestFixtureType::testMethod, \
context.makeFixture() ) ) )
/*! \brief Add a test which fail if the specified exception is not caught.
*
* Example:
* \code
* #include <cppunit/extensions/HelperMacros.h>
* #include <vector>
* class MyTest : public CppUnit::TestFixture {
* CPPUNIT_TEST_SUITE( MyTest );
* CPPUNIT_TEST_EXCEPTION( testVectorAtThrow, std::invalid_argument );
* CPPUNIT_TEST_SUITE_END();
* public:
* void testVectorAtThrow()
* {
* std::vector<int> v;
* v.at( 1 ); // must throw exception std::invalid_argument
* }
* };
* \endcode
*
* \param testMethod Name of the method of the test case to add to the suite.
* \param ExceptionType Type of the exception that must be thrown by the test
* method.
* \deprecated Use the assertion macro CPPUNIT_ASSERT_THROW instead.
*/
#define CPPUNIT_TEST_EXCEPTION( testMethod, ExceptionType ) \
CPPUNIT_TEST_SUITE_ADD_TEST( \
(new CPPUNIT_NS::ExceptionTestCaseDecorator< ExceptionType >( \
new CPPUNIT_NS::TestCaller< TestFixtureType >( \
context.getTestNameFor( #testMethod ), \
&TestFixtureType::testMethod, \
context.makeFixture() ) ) ) )
/*! \brief Adds a test case which is excepted to fail.
*
* The added test case expect an assertion to fail. You usually used that type
* of test case when testing custom assertion macros.
*
* \code
* CPPUNIT_TEST_FAIL( testAssertFalseFail );
*
* void testAssertFalseFail()
* {
* CPPUNIT_ASSERT( false );
* }
* \endcode
* \see CreatingNewAssertions.
* \deprecated Use the assertion macro CPPUNIT_ASSERT_ASSERTION_FAIL instead.
*/
#define CPPUNIT_TEST_FAIL( testMethod ) \
CPPUNIT_TEST_EXCEPTION( testMethod, CPPUNIT_NS::Exception )
/*! \brief Adds some custom test cases.
*
* Use this to add one or more test cases to the fixture suite. The specified
* method is called with a context parameter that can be used to name,
* instantiate fixture, and add instantiated test case to the fixture suite.
* The specified method must have the following signature:
* \code
* static void aMethodName( TestSuiteBuilderContextType &context );
* \endcode
*
* \c TestSuiteBuilderContextType is typedef to
* TestSuiteBuilderContext<TestFixtureType> declared by CPPUNIT_TEST_SUITE().
*
* Here is an example that add two custom tests:
*
* \code
* #include <cppunit/extensions/HelperMacros.h>
*
* class MyTest : public CppUnit::TestFixture {
* CPPUNIT_TEST_SUITE( MyTest );
* CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( addTimeOutTests );
* CPPUNIT_TEST_SUITE_END();
* public:
* static void addTimeOutTests( TestSuiteBuilderContextType &context )
* {
* context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test1" ) ),
* &MyTest::test1,
* context.makeFixture(),
* 5.0 );
* context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test2" ) ),
* &MyTest::test2,
* context.makeFixture(),
* 5.0 );
* }
*
* void test1()
* {
* // Do some test that may never end...
* }
*
* void test2()
* {
* // Do some test that may never end...
* }
* };
* \endcode
* @param testAdderMethod Name of the method called to add the test cases.
*/
#define CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( testAdderMethod ) \
testAdderMethod( context )
/*! \brief Adds a property to the test suite builder context.
* \param APropertyKey Key of the property to add.
* \param APropertyValue Value for the added property.
* Example:
* \code
* CPPUNIT_TEST_SUITE_PROPERTY("XmlFileName", "paraTest.xml"); \endcode
*/
#define CPPUNIT_TEST_SUITE_PROPERTY( APropertyKey, APropertyValue ) \
context.addProperty( std::string(APropertyKey), \
std::string(APropertyValue) )
/** @}
*/
/*! Adds the specified fixture suite to the unnamed registry.
* \ingroup CreatingTestSuite
*
* This macro declares a static variable whose construction
* causes a test suite factory to be inserted in a global registry
* of such factories. The registry is available by calling
* the static function CppUnit::TestFactoryRegistry::getRegistry().
*
* \param ATestFixtureType Type of the test case class.
* \warning This macro should be used only once per line of code (the line
* number is used to name a hidden static variable).
* \see CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
* \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT
* \see CPPUNIT_REGISTRY_ADD
* \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite,
* CppUnit::TestFactoryRegistry.
*/
#define CPPUNIT_TEST_SUITE_REGISTRATION( ATestFixtureType ) \
static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \
CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )
/** Adds the specified fixture suite to the specified registry suite.
* \ingroup CreatingTestSuite
*
* This macro declares a static variable whose construction
* causes a test suite factory to be inserted in the global registry
* suite of the specified name. The registry is available by calling
* the static function CppUnit::TestFactoryRegistry::getRegistry().
*
* For the suite name, use a string returned by a static function rather
* than a hardcoded string. That way, you can know what are the name of
* named registry and you don't risk mistyping the registry name.
*
* \code
* // MySuites.h
* namespace MySuites {
* std::string math() {
* return "Math";
* }
* }
*
* // ComplexNumberTest.cpp
* #include "MySuites.h"
*
* CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ComplexNumberTest, MySuites::math() );
* \endcode
*
* \param ATestFixtureType Type of the test case class.
* \param suiteName Name of the global registry suite the test suite is
* registered into.
* \warning This macro should be used only once per line of code (the line
* number is used to name a hidden static variable).
* \see CPPUNIT_TEST_SUITE_REGISTRATION
* \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT
* \see CPPUNIT_REGISTRY_ADD
* \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite,
* CppUnit::TestFactoryRegistry..
*/
#define CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ATestFixtureType, suiteName ) \
static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType > \
CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )(suiteName)
/*! Adds that the specified registry suite to another registry suite.
* \ingroup CreatingTestSuite
*
* Use this macros to automatically create test registry suite hierarchy. For example,
* if you want to create the following hierarchy:
* - Math
* - IntegerMath
* - FloatMath
* - FastFloat
* - StandardFloat
*
* You can do this automatically with:
* \code
* CPPUNIT_REGISTRY_ADD( "FastFloat", "FloatMath" );
* CPPUNIT_REGISTRY_ADD( "IntegerMath", "Math" );
* CPPUNIT_REGISTRY_ADD( "FloatMath", "Math" );
* CPPUNIT_REGISTRY_ADD( "StandardFloat", "FloatMath" );
* \endcode
*
* There is no specific order of declaration. Think of it as declaring links.
*
* You register the test in each suite using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION.
*
* \param which Name of the registry suite to add to the registry suite named \a to.
* \param to Name of the registry suite \a which is added to.
* \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION.
*/
#define CPPUNIT_REGISTRY_ADD( which, to ) \
static CPPUNIT_NS::AutoRegisterRegistry \
CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which, to )
/*! Adds that the specified registry suite to the default registry suite.
* \ingroup CreatingTestSuite
*
* This macro is just like CPPUNIT_REGISTRY_ADD except the specified registry
* suite is added to the default suite (root suite).
*
* \param which Name of the registry suite to add to the default registry suite.
* \see CPPUNIT_REGISTRY_ADD.
*/
#define CPPUNIT_REGISTRY_ADD_TO_DEFAULT( which ) \
static CPPUNIT_NS::AutoRegisterRegistry \
CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which )
// Backwards compatibility
// (Not tested!)
#if CPPUNIT_ENABLE_CU_TEST_MACROS
#define CU_TEST_SUITE(tc) CPPUNIT_TEST_SUITE(tc)
#define CU_TEST_SUB_SUITE(tc,sc) CPPUNIT_TEST_SUB_SUITE(tc,sc)
#define CU_TEST(tm) CPPUNIT_TEST(tm)
#define CU_TEST_SUITE_END() CPPUNIT_TEST_SUITE_END()
#define CU_TEST_SUITE_REGISTRATION(tc) CPPUNIT_TEST_SUITE_REGISTRATION(tc)
#endif
#endif // CPPUNIT_EXTENSIONS_HELPERMACROS_H

View File

@@ -0,0 +1,95 @@
#ifndef CPPUNIT_EXTENSIONS_ORTHODOX_H
#define CPPUNIT_EXTENSIONS_ORTHODOX_H
#include <cppunit/TestCase.h>
CPPUNIT_NS_BEGIN
/*
* Orthodox performs a simple set of tests on an arbitary
* class to make sure that it supports at least the
* following operations:
*
* default construction - constructor
* equality/inequality - operator== && operator!=
* assignment - operator=
* negation - operator!
* safe passage - copy construction
*
* If operations for each of these are not declared
* the template will not instantiate. If it does
* instantiate, tests are performed to make sure
* that the operations have correct semantics.
*
* Adding an orthodox test to a suite is very
* easy:
*
* public: Test *suite () {
* TestSuite *suiteOfTests = new TestSuite;
* suiteOfTests->addTest (new ComplexNumberTest ("testAdd");
* suiteOfTests->addTest (new TestCaller<Orthodox<Complex> > ());
* return suiteOfTests;
* }
*
* Templated test cases be very useful when you are want to
* make sure that a group of classes have the same form.
*
* see TestSuite
*/
template <class ClassUnderTest> class Orthodox : public TestCase
{
public:
Orthodox () : TestCase ("Orthodox") {}
protected:
ClassUnderTest call (ClassUnderTest object);
void runTest ();
};
// Run an orthodoxy test
template <class ClassUnderTest> void Orthodox<ClassUnderTest>::runTest ()
{
// make sure we have a default constructor
ClassUnderTest a, b, c;
// make sure we have an equality operator
CPPUNIT_ASSERT (a == b);
// check the inverse
b.operator= (a.operator! ());
CPPUNIT_ASSERT (a != b);
// double inversion
b = !!a;
CPPUNIT_ASSERT (a == b);
// invert again
b = !a;
// check calls
c = a;
CPPUNIT_ASSERT (c == call (a));
c = b;
CPPUNIT_ASSERT (c == call (b));
}
// Exercise a call
template <class ClassUnderTest>
ClassUnderTest Orthodox<ClassUnderTest>::call (ClassUnderTest object)
{
return object;
}
CPPUNIT_NS_END
#endif

View File

@@ -0,0 +1,43 @@
#ifndef CPPUNIT_EXTENSIONS_REPEATEDTEST_H
#define CPPUNIT_EXTENSIONS_REPEATEDTEST_H
#include <cppunit/Portability.h>
#include <cppunit/extensions/TestDecorator.h>
CPPUNIT_NS_BEGIN
class Test;
class TestResult;
/*! \brief Decorator that runs a test repeatedly.
*
* Does not assume ownership of the test it decorates
*/
class CPPUNIT_API RepeatedTest : public TestDecorator
{
public:
RepeatedTest( Test *test,
int timesRepeat ) :
TestDecorator( test ),
m_timesRepeat(timesRepeat)
{
}
void run( TestResult *result );
int countTestCases() const;
private:
RepeatedTest( const RepeatedTest & );
void operator=( const RepeatedTest & );
const int m_timesRepeat;
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_REPEATEDTEST_H

View File

@@ -0,0 +1,40 @@
#ifndef CPPUNIT_EXTENSIONS_TESTCASEDECORATOR_H
#define CPPUNIT_EXTENSIONS_TESTCASEDECORATOR_H
#include <cppunit/Portability.h>
#include <cppunit/TestCase.h>
CPPUNIT_NS_BEGIN
/*! \brief Decorator for Test cases.
*
* TestCaseDecorator provides an alternate means to extend functionality
* of a test class without subclassing the test. Instead, one can
* subclass the decorater and use it to wrap the test class.
*
* Does not assume ownership of the test it decorates
*/
class CPPUNIT_API TestCaseDecorator : public TestCase
{
public:
TestCaseDecorator( TestCase *test );
~TestCaseDecorator();
std::string getName() const;
void setUp();
void tearDown();
void runTest();
protected:
TestCase *m_test;
};
CPPUNIT_NS_END
#endif

View File

@@ -0,0 +1,49 @@
#ifndef CPPUNIT_EXTENSIONS_TESTDECORATOR_H
#define CPPUNIT_EXTENSIONS_TESTDECORATOR_H
#include <cppunit/Portability.h>
#include <cppunit/Test.h>
CPPUNIT_NS_BEGIN
class TestResult;
/*! \brief Decorator for Tests.
*
* TestDecorator provides an alternate means to extend functionality
* of a test class without subclassing the test. Instead, one can
* subclass the decorater and use it to wrap the test class.
*
* Does not assume ownership of the test it decorates
*/
class CPPUNIT_API TestDecorator : public Test
{
public:
TestDecorator( Test *test );
~TestDecorator();
int countTestCases() const;
std::string getName() const;
void run( TestResult *result );
int getChildTestCount() const;
protected:
Test *doGetChildTestAt( int index ) const;
Test *m_test;
private:
TestDecorator( const TestDecorator &);
void operator =( const TestDecorator & );
};
CPPUNIT_NS_END
#endif

View File

@@ -0,0 +1,27 @@
#ifndef CPPUNIT_EXTENSIONS_TESTFACTORY_H
#define CPPUNIT_EXTENSIONS_TESTFACTORY_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
class Test;
/*! \brief Abstract Test factory.
*/
class CPPUNIT_API TestFactory
{
public:
virtual ~TestFactory() {}
/*! Makes a new test.
* \return A new Test.
*/
virtual Test* makeTest() = 0;
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_TESTFACTORY_H

View File

@@ -0,0 +1,182 @@
#ifndef CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H
#define CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/portability/CppUnitSet.h>
#include <cppunit/extensions/TestFactory.h>
#include <string>
CPPUNIT_NS_BEGIN
class TestSuite;
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::set<TestFactory *>;
#endif
/*! \brief Registry for TestFactory.
* \ingroup CreatingTestSuite
*
* Notes that the registry \b DON'T assumes lifetime control for any registered tests
* anymore.
*
* The <em>default</em> registry is the registry returned by getRegistry() with the
* default name parameter value.
*
* To register tests, use the macros:
* - CPPUNIT_TEST_SUITE_REGISTRATION(): to add tests in the default registry.
* - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(): to add tests in a named registry.
*
* Example 1: retreiving a suite that contains all the test registered with
* CPPUNIT_TEST_SUITE_REGISTRATION().
* \code
* CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
* CppUnit::TestSuite *suite = registry.makeTest();
* \endcode
*
* Example 2: retreiving a suite that contains all the test registered with
* \link CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" )\endlink.
* \code
* CppUnit::TestFactoryRegistry &mathRegistry = CppUnit::TestFactoryRegistry::getRegistry( "Math" );
* CppUnit::TestSuite *mathSuite = mathRegistry.makeTest();
* \endcode
*
* Example 3: creating a test suite hierarchy composed of unnamed registration and
* named registration:
* - All Tests
* - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Graph" )
* - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" )
* - tests registered with CPPUNIT_TEST_SUITE_REGISTRATION
*
* \code
* CppUnit::TestSuite *rootSuite = new CppUnit::TestSuite( "All tests" );
* rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Graph" ).makeTest() );
* rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Math" ).makeTest() );
* CppUnit::TestFactoryRegistry::getRegistry().addTestToSuite( rootSuite );
* \endcode
*
* The same result can be obtained with:
* \code
* CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
* registry.addRegistry( "Graph" );
* registry.addRegistry( "Math" );
* CppUnit::TestSuite *suite = registry.makeTest();
* \endcode
*
* Since a TestFactoryRegistry is a TestFactory, the named registries can be
* registered in the unnamed registry, creating the hierarchy links.
*
* \see TestSuiteFactory, AutoRegisterSuite
* \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
*/
class CPPUNIT_API TestFactoryRegistry : public TestFactory
{
public:
/** Constructs the registry with the specified name.
* \param name Name of the registry. It is the name of TestSuite returned by
* makeTest().
*/
TestFactoryRegistry( std::string name );
/// Destructor.
virtual ~TestFactoryRegistry();
/** Returns a new TestSuite that contains the registered test.
* \return A new TestSuite which contains all the test added using
* registerFactory(TestFactory *).
*/
virtual Test *makeTest();
/** Returns a named registry.
*
* If the \a name is left to its default value, then the registry that is returned is
* the one used by CPPUNIT_TEST_SUITE_REGISTRATION(): the 'top' level registry.
*
* \param name Name of the registry to return.
* \return Registry. If the registry does not exist, it is created with the
* specified name.
*/
static TestFactoryRegistry &getRegistry( const std::string &name = "All Tests" );
/** Adds the registered tests to the specified suite.
* \param suite Suite the tests are added to.
*/
void addTestToSuite( TestSuite *suite );
/** Adds the specified TestFactory to the registry.
*
* \param factory Factory to register.
*/
void registerFactory( TestFactory *factory );
/*! Removes the specified TestFactory from the registry.
*
* The specified factory is not destroyed.
* \param factory Factory to remove from the registry.
* \todo Address case when trying to remove a TestRegistryFactory.
*/
void unregisterFactory( TestFactory *factory );
/*! Adds a registry to the registry.
*
* Convenience method to help create test hierarchy. See TestFactoryRegistry detail
* for examples of use. Calling this method is equivalent to:
* \code
* this->registerFactory( TestFactoryRegistry::getRegistry( name ) );
* \endcode
*
* \param name Name of the registry to add.
*/
void addRegistry( const std::string &name );
/*! Tests if the registry is valid.
*
* This method should be used when unregistering test factory on static variable
* destruction to ensure that the registry has not been already destroyed (in
* that case there is no need to unregister the test factory).
*
* You should not concern yourself with this method unless you are writing a class
* like AutoRegisterSuite.
*
* \return \c true if the specified registry has not been destroyed,
* otherwise returns \c false.
* \see AutoRegisterSuite.
*/
static bool isValid();
/** Adds the specified TestFactory with a specific name (DEPRECATED).
* \param name Name associated to the factory.
* \param factory Factory to register.
* \deprecated Use registerFactory( TestFactory *) instead.
*/
void registerFactory( const std::string &name,
TestFactory *factory );
private:
TestFactoryRegistry( const TestFactoryRegistry &copy );
void operator =( const TestFactoryRegistry &copy );
private:
typedef CppUnitSet<TestFactory *, std::less<TestFactory*> > Factories;
Factories m_factories;
std::string m_name;
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H

View File

@@ -0,0 +1,50 @@
#ifndef CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H
#define CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
class TestFixture;
/*! \brief Abstract TestFixture factory (Implementation).
*
* Implementation detail. Use by HelperMacros to handle TestFixture hierarchy.
*/
class TestFixtureFactory
{
public:
//! Creates a new TestFixture instance.
virtual TestFixture *makeFixture() =0;
virtual ~TestFixtureFactory() {}
};
/*! \brief Concret TestFixture factory (Implementation).
*
* Implementation detail. Use by HelperMacros to handle TestFixture hierarchy.
*/
template<class TestFixtureType>
class ConcretTestFixtureFactory : public CPPUNIT_NS::TestFixtureFactory
{
/*! \brief Returns a new TestFixture instance.
* \return A new fixture instance. The fixture instance is returned by
* the TestFixtureFactory passed on construction. The actual type
* is that of the fixture on which the static method suite()
* was called.
*/
TestFixture *makeFixture()
{
return new TestFixtureType();
}
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_TESTFIXTUREFACTORY_H

View File

@@ -0,0 +1,89 @@
#ifndef CPPUNIT_EXTENSIONS_TESTNAMER_H
#define CPPUNIT_EXTENSIONS_TESTNAMER_H
#include <cppunit/Portability.h>
#include <string>
#if CPPUNIT_HAVE_RTTI
# include <typeinfo>
#endif
/*! \def CPPUNIT_TESTNAMER_DECL( variableName, FixtureType )
* \brief Declares a TestNamer.
*
* Declares a TestNamer for the specified type, using RTTI if enabled, otherwise
* using macro string expansion.
*
* RTTI is used if CPPUNIT_USE_TYPEINFO_NAME is defined and not null.
*
* \code
* void someMethod()
* {
* CPPUNIT_TESTNAMER_DECL( namer, AFixtureType );
* std::string fixtureName = namer.getFixtureName();
* ...
* \endcode
*
* \relates TestNamer
* \see TestNamer
*/
#if CPPUNIT_USE_TYPEINFO_NAME
# define CPPUNIT_TESTNAMER_DECL( variableName, FixtureType ) \
CPPUNIT_NS::TestNamer variableName( typeid(FixtureType) )
#else
# define CPPUNIT_TESTNAMER_DECL( variableName, FixtureType ) \
CPPUNIT_NS::TestNamer variableName( std::string(#FixtureType) )
#endif
CPPUNIT_NS_BEGIN
/*! \brief Names a test or a fixture suite.
*
* TestNamer is usually instantiated using CPPUNIT_TESTNAMER_DECL.
*
*/
class CPPUNIT_API TestNamer
{
public:
#if CPPUNIT_HAVE_RTTI
/*! \brief Constructs a namer using the fixture's type-info.
* \param typeInfo Type-info of the fixture type. Use to name the fixture suite.
*/
TestNamer( const std::type_info &typeInfo );
#endif
/*! \brief Constructs a namer using the specified fixture name.
* \param fixtureName Name of the fixture suite. Usually extracted using a macro.
*/
TestNamer( const std::string &fixtureName );
virtual ~TestNamer();
/*! \brief Returns the name of the fixture.
* \return Name of the fixture.
*/
virtual std::string getFixtureName() const;
/*! \brief Returns the name of the test for the specified method.
* \param testMethodName Name of the method that implements a test.
* \return A string that is the concatenation of the test fixture name
* (returned by getFixtureName()) and\a testMethodName,
* separated using '::'. This provides a fairly unique name for a given
* test.
*/
virtual std::string getTestNameFor( const std::string &testMethodName ) const;
protected:
std::string m_fixtureName;
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_TESTNAMER_H

View File

@@ -0,0 +1,34 @@
#ifndef CPPUNIT_EXTENSIONS_TESTSETUP_H
#define CPPUNIT_EXTENSIONS_TESTSETUP_H
#include <cppunit/extensions/TestDecorator.h>
CPPUNIT_NS_BEGIN
class Test;
class TestResult;
/*! \brief Decorates a test by providing a specific setUp() and tearDown().
*/
class CPPUNIT_API TestSetUp : public TestDecorator
{
public:
TestSetUp( Test *test );
void run( TestResult *result );
protected:
virtual void setUp();
virtual void tearDown();
private:
TestSetUp( const TestSetUp & );
void operator =( const TestSetUp & );
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_TESTSETUP_H

View File

@@ -0,0 +1,131 @@
#ifndef CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H
#define CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H
#include <cppunit/Portability.h>
#include <cppunit/portability/CppUnitMap.h>
#include <string>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
CPPUNIT_NS_BEGIN
class TestSuite;
class TestFixture;
class TestFixtureFactory;
class TestNamer;
/*! \brief Context used when creating test suite in HelperMacros.
*
* Base class for all context used when creating test suite. The
* actual context type during test suite creation is TestSuiteBuilderContext.
*
* \sa CPPUNIT_TEST_SUITE, CPPUNIT_TEST_SUITE_ADD_TEST,
* CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS.
*/
class CPPUNIT_API TestSuiteBuilderContextBase
{
public:
/*! \brief Constructs a new context.
*
* You should not use this. The context is created in
* CPPUNIT_TEST_SUITE().
*/
TestSuiteBuilderContextBase( TestSuite &suite,
const TestNamer &namer,
TestFixtureFactory &factory );
virtual ~TestSuiteBuilderContextBase();
/*! \brief Adds a test to the fixture suite.
*
* \param test Test to add to the fixture suite. Must not be \c NULL.
*/
void addTest( Test *test );
/*! \brief Returns the fixture name.
* \return Fixture name. It is the name used to name the fixture
* suite.
*/
std::string getFixtureName() const;
/*! \brief Returns the name of the test for the specified method.
*
* \param testMethodName Name of the method that implements a test.
* \return A string that is the concatenation of the test fixture name
* (returned by getFixtureName()) and\a testMethodName,
* separated using '::'. This provides a fairly unique name for a given
* test.
*/
std::string getTestNameFor( const std::string &testMethodName ) const;
/*! \brief Adds property pair.
* \param key PropertyKey string to add.
* \param value PropertyValue string to add.
*/
void addProperty( const std::string &key,
const std::string &value );
/*! \brief Returns property value assigned to param key.
* \param key PropertyKey string.
*/
const std::string getStringProperty( const std::string &key ) const;
protected:
TestFixture *makeTestFixture() const;
// Notes: we use a vector here instead of a map to work-around the
// shared std::map in dll bug in VC6.
// See http://www.dinkumware.com/vc_fixes.html for detail.
typedef std::pair<std::string,std::string> Property;
typedef CppUnitVector<Property> Properties;
TestSuite &m_suite;
const TestNamer &m_namer;
TestFixtureFactory &m_factory;
private:
Properties m_properties;
};
/*! \brief Type-sage context used when creating test suite in HelperMacros.
*
* \sa TestSuiteBuilderContextBase.
*/
template<class Fixture>
class TestSuiteBuilderContext : public TestSuiteBuilderContextBase
{
public:
typedef Fixture FixtureType;
TestSuiteBuilderContext( TestSuiteBuilderContextBase &contextBase )
: TestSuiteBuilderContextBase( contextBase )
{
}
/*! \brief Returns a new TestFixture instance.
* \return A new fixture instance. The fixture instance is returned by
* the TestFixtureFactory passed on construction. The actual type
* is that of the fixture on which the static method suite()
* was called.
*/
FixtureType *makeFixture() const
{
return CPPUNIT_STATIC_CAST( FixtureType *,
TestSuiteBuilderContextBase::makeTestFixture() );
}
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_HELPER_TESTSUITEBUILDERCONTEXT_H

View File

@@ -0,0 +1,27 @@
#ifndef CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H
#define CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H
#include <cppunit/extensions/TestFactory.h>
CPPUNIT_NS_BEGIN
class Test;
/*! \brief TestFactory for TestFixture that implements a static suite() method.
* \see AutoRegisterSuite.
*/
template<class TestCaseType>
class TestSuiteFactory : public TestFactory
{
public:
virtual Test *makeTest()
{
return TestCaseType::suite();
}
};
CPPUNIT_NS_END
#endif // CPPUNIT_EXTENSIONS_TESTSUITEFACTORY_H

View File

@@ -0,0 +1,33 @@
#ifndef CPPUNIT_TYPEINFOHELPER_H
#define CPPUNIT_TYPEINFOHELPER_H
#include <cppunit/Portability.h>
#if CPPUNIT_HAVE_RTTI
#include <typeinfo>
#include <string>
CPPUNIT_NS_BEGIN
/**! \brief Helper to use type_info.
*/
class CPPUNIT_API TypeInfoHelper
{
public:
/*! \brief Get the class name of the specified type_info.
* \param info Info which the class name is extracted from.
* \return The string returned by type_info::name() without
* the "class" prefix. If the name is not prefixed
* by "class", it is returned as this.
*/
static std::string getClassName( const std::type_info &info );
};
CPPUNIT_NS_END
#endif // CPPUNIT_HAVE_RTTI
#endif // CPPUNIT_TYPEINFOHELPER_H

View File

@@ -0,0 +1,23 @@
#ifndef CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H
#define CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H
#include <cppunit/ParameterizedTestCase.h>
/*! \brief Adds a parameterized test method to the suite.
* \param testMethod Name of the method of the test case to add to the
* suite. The signature of the method must be of
* type: void testMethod(std::istream& param_in, std::istream& exp_in);
* \see CPPUNIT_TEST_SUITE.
*/
#define CPPUNIT_TEST_XML( testMethod) \
CPPUNIT_TEST_ADD( new CppUnit::ParameterizedTestCase<ThisTestFixtureType>( \
context.getTestNameFor( #testMethod ), \
#testMethod, \
&TestFixtureType::testMethod, \
context.makeFixture(), \
context.getStringProperty( std::string("XmlFileName") ) ) )
#endif // CPPUNIT_EXTENSIONS_XMLINPUTHELPER_H

View File

@@ -0,0 +1,121 @@
#ifndef CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H
#define CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H
#include <cppunit/Portability.h>
#include <string>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
CPPUNIT_NS_BEGIN
/*! \brief Manages dynamic libraries.
*
* The Dynamic Library Manager provides a platform independent way to work with
* dynamic library. It load a specific dynamic library, and can returns specific
* symbol exported by the dynamic library.
*
* If an error occurs, a DynamicLibraryManagerException is thrown.
*
* \internal Implementation of the OS independent methods is in
* DynamicLibraryManager.cpp.
*
* \internal Porting to a new platform:
* - Adds platform detection in config/SelectDllLoader.h. Should define a specific
* macro for that platform of the form: CPPUNIT_HAVE_XYZ_DLL_LOADER, where
* XYZ is the platform.
* - Makes a copy of UnixDynamicLibraryManager.cpp and named it after the platform.
* - Updated the 'guard' in your file (CPPUNIT_HAVE_XYZ_DLL_LOADER) so that it is
* only processed if the matching platform has been detected.
* - Change the implementation of methods doLoadLibrary(), doReleaseLibrary(),
* doFindSymbol() in your copy. Those methods usually maps directly to OS calls.
* - Adds the file to the project.
*/
class DynamicLibraryManager
{
public:
typedef void *Symbol;
typedef void *LibraryHandle;
/*! \brief Loads the specified library.
* \param libraryFileName Name of the library to load.
* \exception DynamicLibraryManagerException if a failure occurs while loading
* the library (fail to found or load the library).
*/
DynamicLibraryManager( const std::string &libraryFileName );
/// Releases the loaded library..
~DynamicLibraryManager();
/*! \brief Returns a pointer on the specified symbol exported by the library.
* \param symbol Name of the symbol exported by the library.
* \return Pointer on the symbol. Should be casted to the actual type. Never \c NULL.
* \exception DynamicLibraryManagerException if the symbol is not found.
*/
Symbol findSymbol( const std::string &symbol );
private:
/*! Loads the specified library.
* \param libraryName Name of the library to load.
* \exception DynamicLibraryManagerException if a failure occurs while loading
* the library (fail to found or load the library).
*/
void loadLibrary( const std::string &libraryName );
/*! Releases the loaded library.
*
* \warning Must NOT throw any exceptions (called from destructor).
*/
void releaseLibrary();
/*! Loads the specified library.
*
* May throw any exceptions (indicates failure).
* \param libraryName Name of the library to load.
* \return Handle of the loaded library. \c NULL indicates failure.
*/
LibraryHandle doLoadLibrary( const std::string &libraryName );
/*! Releases the loaded library.
*
* The handle of the library to free is in \c m_libraryHandle. It is never
* \c NULL.
* \warning Must NOT throw any exceptions (called from destructor).
*/
void doReleaseLibrary();
/*! Returns a pointer on the specified symbol exported by the library.
*
* May throw any exceptions (indicates failure).
* \param symbol Name of the symbol exported by the library.
* \return Pointer on the symbol. \c NULL indicates failure.
*/
Symbol doFindSymbol( const std::string &symbol );
/*! Returns detailed information about doLoadLibrary() failure.
*
* Called just after a failed call to doLoadLibrary() to get extra
* error information.
*
* \return Detailed information about the failure of the call to
* doLoadLibrary() that just failed.
*/
std::string getLastErrorDetail() const;
/// Prevents the use of the copy constructor.
DynamicLibraryManager( const DynamicLibraryManager &copy );
/// Prevents the use of the copy operator.
void operator =( const DynamicLibraryManager &copy );
private:
LibraryHandle m_libraryHandle;
std::string m_libraryName;
};
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGER_H

View File

@@ -0,0 +1,53 @@
#ifndef CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H
#define CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H
#include <cppunit/Portability.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <stdexcept>
#include <string>
CPPUNIT_NS_BEGIN
/*! \brief Exception thrown by DynamicLibraryManager when a failure occurs.
*
* Use getCause() to know what function caused the failure.
*
*/
class DynamicLibraryManagerException : public std::runtime_error
{
public:
enum Cause
{
/// Failed to load the dynamic library
loadingFailed =0,
/// Symbol not found in the dynamic library
symbolNotFound
};
/// Failed to load the dynamic library or Symbol not found in the dynamic library.
DynamicLibraryManagerException( const std::string &libraryName,
const std::string &errorDetail,
Cause cause );
~DynamicLibraryManagerException() throw()
{
}
Cause getCause() const;
const char *what() const throw();
private:
std::string m_message;
Cause m_cause;
};
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_DYNAMICLIBRARYMANAGEREXCEPTION_H

View File

@@ -0,0 +1,113 @@
#ifndef CPPUNIT_PLUGIN_PLUGINMANAGER_H
#define CPPUNIT_PLUGIN_PLUGINMANAGER_H
#include <cppunit/Portability.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/plugin/PlugInParameters.h>
struct CppUnitTestPlugIn;
CPPUNIT_NS_BEGIN
class DynamicLibraryManager;
class TestResult;
class XmlOutputter;
/*! \brief Manges TestPlugIn.
*/
class CPPUNIT_API PlugInManager
{
public:
/*! Constructs a PlugInManager object.
*/
PlugInManager();
/// Destructor.
virtual ~PlugInManager();
/*! \brief Loads the specified plug-in.
*
* After being loaded, the CppUnitTestPlugIn::initialize() is called.
*
* \param libraryFileName Name of the file that contains the TestPlugIn.
* \param parameters List of string passed to the plug-in.
* \return Pointer on the DynamicLibraryManager associated to the library.
* Valid until the library is unloaded. Never \c NULL.
* \exception DynamicLibraryManagerException is thrown if an error occurs during loading.
*/
void load( const std::string &libraryFileName,
const PlugInParameters &parameters = PlugInParameters() );
/*! \brief Unloads the specified plug-in.
* \param libraryFileName Name of the file that contains the TestPlugIn passed
* to a previous call to load().
*/
void unload( const std::string &libraryFileName );
/*! \brief Gives a chance to each loaded plug-in to register TestListener.
*
* For each plug-in, call CppUnitTestPlugIn::addListener().
*/
void addListener( TestResult *eventManager );
/*! \brief Gives a chance to each loaded plug-in to unregister TestListener.
* For each plug-in, call CppUnitTestPlugIn::removeListener().
*/
void removeListener( TestResult *eventManager );
/*! \brief Provides a way for the plug-in to register some XmlOutputterHook.
*/
void addXmlOutputterHooks( XmlOutputter *outputter );
/*! \brief Called when the XmlOutputter is destroyed.
*
* Can be used to free some resources allocated by addXmlOutputterHooks().
*/
void removeXmlOutputterHooks();
protected:
/*! \brief (INTERNAL) Information about a specific plug-in.
*/
struct PlugInInfo
{
std::string m_fileName;
DynamicLibraryManager *m_manager;
CppUnitTestPlugIn *m_interface;
};
/*! Unloads the specified plug-in.
* \param plugIn Information about the plug-in.
*/
void unload( PlugInInfo &plugIn );
private:
/// Prevents the use of the copy constructor.
PlugInManager( const PlugInManager &copy );
/// Prevents the use of the copy operator.
void operator =( const PlugInManager &copy );
private:
typedef CppUnitDeque<PlugInInfo> PlugIns;
PlugIns m_plugIns;
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_PLUGINMANAGER_H

View File

@@ -0,0 +1,36 @@
#ifndef CPPUNIT_PLUGIN_PARAMETERS
#define CPPUNIT_PLUGIN_PARAMETERS
#include <cppunit/Portability.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <cppunit/portability/CppUnitDeque.h>
#include <string>
CPPUNIT_NS_BEGIN
/*! \brief Test plug-ins parameters.
*/
class CPPUNIT_API PlugInParameters
{
public:
/// Constructs plug-in parameters from the specified command-line.
PlugInParameters( const std::string &commandLine = "" );
virtual ~PlugInParameters();
/// Returns the command line that was passed on construction.
std::string getCommandLine() const;
private:
std::string m_commandLine;
};
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_PARAMETERS

View File

@@ -0,0 +1,200 @@
#ifndef CPPUNIT_PLUGIN_TESTPLUGIN
#define CPPUNIT_PLUGIN_TESTPLUGIN
#include <cppunit/Portability.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <cppunit/plugin/PlugInParameters.h>
CPPUNIT_NS_BEGIN
class Test;
class TestFactoryRegistry;
class TestResult;
class XmlOutputter;
CPPUNIT_NS_END
/*! \file
*/
/*! \brief Test plug-in interface.
* \ingroup WritingTestPlugIn
*
* This class define the interface implemented by test plug-in. A pointer to that
* interface is returned by the function exported by the test plug-in.
*
* Plug-in are loaded/unloaded by PlugInManager. When a plug-in is loaded,
* initialize() is called. Before unloading the plug-in, the PlugInManager
* call uninitialize().
*
* addListener() and removeListener() are called respectively before and after
* the test run.
*
* addXmlOutputterHooks() and removeXmlOutputterHooks() are called respectively
* before and after writing the XML output using a XmlOutputter.
*
* \see CPPUNIT_PLUGIN_IMPLEMENT, CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL
* \see CppUnit::TestPlugInDefaultImpl, CppUnit::XmlOutputter.
*/
struct CPPUNIT_API CppUnitTestPlugIn
{
/*! \brief Called just after loading the dynamic library.
*
* Override this method to add additional suite to the registry, though this
* is preferably done using the macros (CPPUNIT_TEST_SUITE_REGISTRATION...).
* If you are creating a custom listener to extends the plug-in runner,
* you can use this to configure the listener using the \a parameters.
*
* You could also use the parameters to specify some global parameter, such
* as test datas location, database name...
*
* N.B.: Parameters interface is not define yet, and the plug-in runner does
* not yet support plug-in parameter.
*/
virtual void initialize( CPPUNIT_NS::TestFactoryRegistry *registry,
const CPPUNIT_NS::PlugInParameters &parameters ) =0;
/*! \brief Gives a chance to the plug-in to register TestListener.
*
* Override this method to add a TestListener for the test run. This is useful
* if you are writing a custom TestListener, but also if you need to
* setUp some global resource: listen to TestListener::startTestRun(),
* and TestListener::endTestRun().
*/
virtual void addListener( CPPUNIT_NS::TestResult *eventManager ) =0;
/*! \brief Gives a chance to the plug-in to remove its registered TestListener.
*
* Override this method to remove a TestListener that has been added.
*/
virtual void removeListener( CPPUNIT_NS::TestResult *eventManager ) =0;
/*! \brief Provides a way for the plug-in to register some XmlOutputterHook.
*/
virtual void addXmlOutputterHooks( CPPUNIT_NS::XmlOutputter *outputter ) =0;
/*! \brief Called when the XmlOutputter is destroyed.
*
* Can be used to free some resources allocated by addXmlOutputterHooks().
*/
virtual void removeXmlOutputterHooks() = 0;
/*! \brief Called just before unloading the dynamic library.
*
* Override this method to unregister test factory added in initialize().
* This is necessary to keep the TestFactoryRegistry 'clean'. When
* the plug-in is unloaded from memory, the TestFactoryRegistry will hold
* reference on test that are no longer available if they are not
* unregistered.
*/
virtual void uninitialize( CPPUNIT_NS::TestFactoryRegistry *registry ) =0;
virtual ~CppUnitTestPlugIn() {}
};
/*! \brief Name of the function exported by a test plug-in.
* \ingroup WritingTestPlugIn
*
* The signature of the exported function is:
* \code
* CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void);
* \endcode
*/
#define CPPUNIT_PLUGIN_EXPORTED_NAME cppunitTestPlugIn
/*! \brief Type of the function exported by a plug-in.
* \ingroup WritingTestPlugIn
*/
typedef CppUnitTestPlugIn *(*TestPlugInSignature)();
/*! \brief Implements the function exported by the test plug-in
* \ingroup WritingTestPlugIn
*/
#define CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( TestPlugInInterfaceType ) \
CPPUNIT_PLUGIN_EXPORT CppUnitTestPlugIn *CPPUNIT_PLUGIN_EXPORTED_NAME(void) \
{ \
static TestPlugInInterfaceType plugIn; \
return &plugIn; \
} \
typedef char __CppUnitPlugInExportFunctionDummyTypeDef // dummy typedef so it can end with ';'
// Note: This include should remain after definition of CppUnitTestPlugIn
#include <cppunit/plugin/TestPlugInDefaultImpl.h>
/*! \def CPPUNIT_PLUGIN_IMPLEMENT_MAIN()
* \brief Implements the 'main' function for the plug-in.
*
* This macros implements the main() function for dynamic library.
* For example, WIN32 requires a DllMain function, while some Unix
* requires a main() function. This macros takes care of the implementation.
*/
// Win32
#if defined(CPPUNIT_HAVE_WIN32_DLL_LOADER)
#if !defined(APIENTRY)
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOUSER
#define NOKERNEL
#define NOSOUND
#define NOMINMAX
#define BLENDFUNCTION void // for mingw & gcc
#include <windows.h>
#endif
#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
BOOL APIENTRY DllMain( HANDLE hModule, \
DWORD ul_reason_for_call, \
LPVOID lpReserved ) \
{ \
return TRUE; \
} \
typedef char __CppUnitPlugInImplementMainDummyTypeDef
// Unix
#elif defined(CPPUNIT_HAVE_UNIX_DLL_LOADER) || defined(CPPUNIT_HAVE_UNIX_SHL_LOADER)
#define CPPUNIT_PLUGIN_IMPLEMENT_MAIN() \
int main( int argc, char *argv[] ) \
{ \
return 0; \
} \
typedef char __CppUnitPlugInImplementMainDummyTypeDef
// Other
#else // other platforms don't require anything specifics
#endif
/*! \brief Implements and exports the test plug-in interface.
* \ingroup WritingTestPlugIn
*
* This macro exports the test plug-in function using the subclass,
* and implements the 'main' function for the plug-in using
* CPPUNIT_PLUGIN_IMPLEMENT_MAIN().
*
* When using this macro, CppUnit must be linked as a DLL (shared library).
* Otherwise, tests registered to the TestFactoryRegistry in the DLL will
* not be visible to the DllPlugInTester.
*
* \see CppUnitTestPlugIn
* \see CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL(), CPPUNIT_PLUGIN_IMPLEMENT_MAIN().
*/
#define CPPUNIT_PLUGIN_IMPLEMENT() \
CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( CPPUNIT_NS::TestPlugInDefaultImpl ); \
CPPUNIT_PLUGIN_IMPLEMENT_MAIN()
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_TESTPLUGIN

View File

@@ -0,0 +1,61 @@
#ifndef CPPUNIT_PLUGIN_TESTPLUGINADAPTER
#define CPPUNIT_PLUGIN_TESTPLUGINADAPTER
#include <cppunit/Portability.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <cppunit/plugin/TestPlugIn.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 4660 ) // X needs to have dll-interface to be used by clients of class Z
#endif
CPPUNIT_NS_BEGIN
class TestSuite;
/*! \brief Default implementation of test plug-in interface.
* \ingroup WritingTestPlugIn
*
* Override getSuiteName() to specify the suite name. Default is "All Tests".
*
* CppUnitTestPlugIn::getTestSuite() returns a suite that contains
* all the test registered to the default test factory registry
* ( TestFactoryRegistry::getRegistry() ).
*
*/
class CPPUNIT_API TestPlugInDefaultImpl : public CppUnitTestPlugIn
{
public:
TestPlugInDefaultImpl();
virtual ~TestPlugInDefaultImpl();
void initialize( TestFactoryRegistry *registry,
const PlugInParameters &parameters );
void addListener( TestResult *eventManager );
void removeListener( TestResult *eventManager );
void addXmlOutputterHooks( XmlOutputter *outputter );
void removeXmlOutputterHooks();
void uninitialize( TestFactoryRegistry *registry );
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)
#endif // CPPUNIT_PLUGIN_TESTPLUGINADAPTER

View File

@@ -0,0 +1,25 @@
#ifndef CPPUNIT_PORTABILITY_CPPUNITDEQUE_H
#define CPPUNIT_PORTABILITY_CPPUNITDEQUE_H
// The technic used is similar to the wrapper of STLPort.
#include <cppunit/Portability.h>
#include <deque>
#if CPPUNIT_STD_NEED_ALLOCATOR
template<class T>
class CppUnitDeque : public std::deque<T,CPPUNIT_STD_ALLOCATOR>
{
public:
};
#else // CPPUNIT_STD_NEED_ALLOCATOR
#define CppUnitDeque std::deque
#endif
#endif // CPPUNIT_PORTABILITY_CPPUNITDEQUE_H

View File

@@ -0,0 +1,29 @@
#ifndef CPPUNIT_PORTABILITY_CPPUNITMAP_H
#define CPPUNIT_PORTABILITY_CPPUNITMAP_H
// The technic used is similar to the wrapper of STLPort.
#include <cppunit/Portability.h>
#include <functional>
#include <map>
#if CPPUNIT_STD_NEED_ALLOCATOR
template<class Key, class T>
class CppUnitMap : public std::map<Key
,T
,std::less<Key>
,CPPUNIT_STD_ALLOCATOR>
{
public:
};
#else // CPPUNIT_STD_NEED_ALLOCATOR
#define CppUnitMap std::map
#endif
#endif // CPPUNIT_PORTABILITY_CPPUNITMAP_H

View File

@@ -0,0 +1,28 @@
#ifndef CPPUNIT_PORTABILITY_CPPUNITSET_H
#define CPPUNIT_PORTABILITY_CPPUNITSET_H
// The technic used is similar to the wrapper of STLPort.
#include <cppunit/Portability.h>
#include <functional>
#include <set>
#if CPPUNIT_STD_NEED_ALLOCATOR
template<class T>
class CppUnitSet : public std::set<T
,std::less<T>
,CPPUNIT_STD_ALLOCATOR>
{
public:
};
#else // CPPUNIT_STD_NEED_ALLOCATOR
#define CppUnitSet std::set
#endif
#endif // CPPUNIT_PORTABILITY_CPPUNITSET_H

View File

@@ -0,0 +1,26 @@
#ifndef CPPUNIT_PORTABILITY_CPPUNITSTACK_H
#define CPPUNIT_PORTABILITY_CPPUNITSTACK_H
// The technic used is similar to the wrapper of STLPort.
#include <cppunit/Portability.h>
#include <deque>
#include <stack>
#if CPPUNIT_STD_NEED_ALLOCATOR
template<class T>
class CppUnitStack : public std::stack<T
,std::deque<T,CPPUNIT_STD_ALLOCATOR> >
{
public:
};
#else // CPPUNIT_STD_NEED_ALLOCATOR
#define CppUnitStack std::stack
#endif
#endif // CPPUNIT_PORTABILITY_CPPUNITSTACK_H

View File

@@ -0,0 +1,25 @@
#ifndef CPPUNIT_PORTABILITY_CPPUNITVECTOR_H
#define CPPUNIT_PORTABILITY_CPPUNITVECTOR_H
// The technic used is similar to the wrapper of STLPort.
#include <cppunit/Portability.h>
#include <vector>
#if CPPUNIT_STD_NEED_ALLOCATOR
template<class T>
class CppUnitVector : public std::vector<T,CPPUNIT_STD_ALLOCATOR>
{
public:
};
#else // CPPUNIT_STD_NEED_ALLOCATOR
#define CppUnitVector std::vector
#endif
#endif // CPPUNIT_PORTABILITY_CPPUNITVECTOR_H

View File

@@ -0,0 +1,54 @@
#ifndef CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
#define CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED
#include <cppunit/Portability.h>
#include <math.h>
CPPUNIT_NS_BEGIN
/// \brief Tests if a floating-point is a NaN.
// According to IEEE-754 floating point standard,
// (see e.g. page 8 of
// http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps)
// all comparisons with NaN are false except "x != x", which is true.
//
// At least Microsoft Visual Studio 6 is known not to implement this test correctly.
// It emits the following code to test equality:
// fcomp qword ptr [nan]
// fnstsw ax // copie fp (floating-point) status register to ax
// test ah,40h // test bit 14 of ax (0x4000) => C3 of fp status register
// According to the following documentation on the x86 floating point status register,
// the C2 bit should be tested to test for NaN value.
// http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117
// In Microsoft Visual Studio 2003 & 2005, the test is implemented with:
// test ah,44h // Visual Studio 2005 test both C2 & C3...
//
// To work around this, a NaN is assumed to be detected if no strict ordering is found.
inline bool floatingPointIsUnordered( double x )
{
// x != x will detect a NaN on conformant platform
// (2.0 < x && x < 1.0) will detect a NaN on non conformant platform:
// => no ordering can be found for x.
return (x != x) || (2.0 < x && x < 1.0);
}
/// \brief Tests if a floating-point is finite.
/// @return \c true if x is neither a NaN, nor +inf, nor -inf, \c false otherwise.
inline int floatingPointIsFinite( double x )
{
#if defined(CPPUNIT_HAVE_ISFINITE)
return isfinite( x );
#elif defined(CPPUNIT_HAVE_FINITE)
return finite( x );
#elif defined(CPPUNIT_HAVE__FINITE)
return _finite(x);
#else
double testInf = x * 0.0; // Produce 0.0 if x is finite, a NaN otherwise.
return testInf == 0.0 && !floatingPointIsUnordered(testInf);
#endif
}
CPPUNIT_NS_END
#endif // CPPUNIT_PORTABILITY_FLOATINGPOINT_H_INCLUDED

View File

@@ -0,0 +1,347 @@
#ifndef CPPUNIT_PORTABILITY_STREAM_H_INCLUDED
#define CPPUNIT_PORTABILITY_STREAM_H_INCLUDED
// This module define:
// Type CppUT::Stream (either std::stream or a custom type)
// Type CppUT::OStringStream (eitjer std::ostringstream, older alternate or a custom type)
// Functions stdCOut() & stdCErr() which returns a reference on cout & cerr stream (or our
// custom stream).
#include <cppunit/Portability.h>
#if defined( CPPUNIT_NO_STREAM )
#include <string>
#include <stdio.h>
#include <string.h>
CPPUNIT_NS_BEGIN
class StreamBuffer
{
public:
virtual ~StreamBuffer() {}
virtual void write( const char *text, unsigned int length ) = 0;
virtual void flush() {}
};
class StringStreamBuffer : public StreamBuffer
{
public:
std::string str() const
{
return str_;
}
public: // overridden from StreamBuffer
void write( const char *text, unsigned int length )
{
str_.append( text, length );
}
private:
std::string str_;
};
class FileStreamBuffer : public StreamBuffer
{
public:
FileStreamBuffer( FILE *file )
: file_( file )
{
}
FILE *file() const
{
return file_;
}
public: // overridden from StreamBuffer
void write( const char *text, unsigned int length )
{
if ( file_ )
fwrite( text, sizeof(char), length, file_ );
}
void flush()
{
if ( file_ )
fflush( file_ );
}
private:
FILE *file_;
};
class OStream
{
public:
OStream()
: buffer_( 0 )
{
}
OStream( StreamBuffer *buffer )
: buffer_( buffer )
{
}
virtual ~OStream()
{
flush();
}
OStream &flush()
{
if ( buffer_ )
buffer_->flush();
return *this;
}
void setBuffer( StreamBuffer *buffer )
{
buffer_ = buffer;
}
OStream &write( const char *text, unsigned int length )
{
if ( buffer_ )
buffer_->write( text, length );
return *this;
}
OStream &write( const char *text )
{
return write( text, strlen(text) );
}
OStream &operator <<( bool v )
{
const char *out = v ? "true" : "false";
return write( out );
}
OStream &operator <<( short v )
{
char buffer[64];
sprintf( buffer, "%hd", v );
return write( buffer );
}
OStream &operator <<( unsigned short v )
{
char buffer[64];
sprintf( buffer, "%hu", v );
return write( buffer );
}
OStream &operator <<( int v )
{
char buffer[64];
sprintf( buffer, "%d", v );
return write( buffer );
}
OStream &operator <<( unsigned int v )
{
char buffer[64];
sprintf( buffer, "%u", v );
return write( buffer );
}
OStream &operator <<( long v )
{
char buffer[64];
sprintf( buffer, "%ld", v );
return write( buffer );
}
OStream &operator <<( unsigned long v )
{
char buffer[64];
sprintf( buffer, "%lu", v );
return write( buffer );
}
OStream &operator <<( float v )
{
char buffer[128];
sprintf( buffer, "%.16g", double(v) );
return write( buffer );
}
OStream &operator <<( double v )
{
char buffer[128];
sprintf( buffer, "%.16g", v );
return write( buffer );
}
OStream &operator <<( long double v )
{
char buffer[128];
sprintf( buffer, "%.16g", double(v) );
return write( buffer );
}
OStream &operator <<( const void *v )
{
char buffer[64];
sprintf( buffer, "%p", v );
return write( buffer );
}
OStream &operator <<( const char *v )
{
return write( v ? v : "NULL" );
}
OStream &operator <<( char c )
{
char buffer[16];
sprintf( buffer, "%c", c );
return write( buffer );
}
OStream &operator <<( const std::string &s )
{
return write( s.c_str(), s.length() );
}
private:
StreamBuffer *buffer_;
};
class OStringStream : public OStream
{
public:
OStringStream()
: OStream( &buffer_ )
{
}
std::string str() const
{
return buffer_.str();
}
private:
StringStreamBuffer buffer_;
};
class OFileStream : public OStream
{
public:
OFileStream( FILE *file )
: OStream( &buffer_ )
, buffer_( file )
, ownFile_( false )
{
}
OFileStream( const char *path )
: OStream( &buffer_ )
, buffer_( fopen( path, "wt" ) )
, ownFile_( true )
{
}
virtual ~OFileStream()
{
if ( ownFile_ && buffer_.file() )
fclose( buffer_.file() );
}
private:
FileStreamBuffer buffer_;
bool ownFile_;
};
inline OStream &stdCOut()
{
static OFileStream stream( stdout );
return stream;
}
inline OStream &stdCErr()
{
static OFileStream stream( stderr );
return stream;
}
CPPUNIT_NS_END
#elif CPPUNIT_HAVE_SSTREAM // #if defined( CPPUNIT_NO_STREAM )
# include <sstream>
# include <fstream>
CPPUNIT_NS_BEGIN
typedef std::ostringstream OStringStream; // The standard C++ way
typedef std::ofstream OFileStream;
CPPUNIT_NS_END
#elif CPPUNIT_HAVE_CLASS_STRSTREAM
# include <string>
# if CPPUNIT_HAVE_STRSTREAM
# include <strstream>
# else // CPPUNIT_HAVE_STRSTREAM
# include <strstream.h>
# endif // CPPUNIT_HAVE_CLASS_STRSTREAM
CPPUNIT_NS_BEGIN
class OStringStream : public std::ostrstream
{
public:
std::string str()
{
// (*this) << '\0';
// std::string msg(std::ostrstream::str());
// std::ostrstream::freeze(false);
// return msg;
// Alternative implementation that don't rely on freeze which is not
// available on some platforms:
return std::string( std::ostrstream::str(), pcount() );
}
};
CPPUNIT_NS_END
#else // CPPUNIT_HAVE_CLASS_STRSTREAM
# error Cannot define CppUnit::OStringStream.
#endif // #if defined( CPPUNIT_NO_STREAM )
#if !defined( CPPUNIT_NO_STREAM )
#include <iostream>
CPPUNIT_NS_BEGIN
typedef std::ostream OStream;
inline OStream &stdCOut()
{
return std::cout;
}
inline OStream &stdCErr()
{
return std::cerr;
}
CPPUNIT_NS_END
#endif // #if !defined( CPPUNIT_NO_STREAM )
#endif // CPPUNIT_PORTABILITY_STREAM_H_INCLUDED

View File

@@ -0,0 +1,23 @@
#ifndef CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED
#define CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED
#include <cppunit/Portability.h>
CPPUNIT_NS_BEGIN
template<class SequenceType, class ValueType>
void
removeFromSequence( SequenceType &sequence,
const ValueType &valueToRemove )
{
for ( unsigned int index =0; index < sequence.size(); ++index )
{
if ( sequence[ index ] == valueToRemove )
sequence.erase( sequence.begin() + index );
}
}
CPPUNIT_NS_END
#endif // CPPUNIT_TOOLS_ALGORITHM_H_INCLUDED

View File

@@ -0,0 +1,34 @@
#ifndef CPPUNIT_TOOLS_STRINGTOOLS_H
#define CPPUNIT_TOOLS_STRINGTOOLS_H
#include <cppunit/Portability.h>
#include <string>
#include <cppunit/portability/CppUnitVector.h>
CPPUNIT_NS_BEGIN
/*! \brief Tool functions to manipulate string.
*/
struct StringTools
{
typedef CppUnitVector<std::string> Strings;
static std::string CPPUNIT_API toString( int value );
static std::string CPPUNIT_API toString( double value );
static Strings CPPUNIT_API split( const std::string &text,
char separator );
static std::string CPPUNIT_API wrap( const std::string &text,
int wrapColumn = CPPUNIT_WRAP_COLUMN );
};
CPPUNIT_NS_END
#endif // CPPUNIT_TOOLS_STRINGTOOLS_H

View File

@@ -0,0 +1,86 @@
#ifndef CPPUNIT_TOOLS_XMLDOCUMENT_H
#define CPPUNIT_TOOLS_XMLDOCUMENT_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <string>
CPPUNIT_NS_BEGIN
class XmlElement;
/*! \brief A XML Document.
*
* A XmlDocument represents a XML file. It holds a pointer on the root XmlElement
* of the document. It also holds the encoding and style sheet used.
*
* By default, the XML document is stand-alone and tagged with enconding "ISO-8859-1".
*/
class CPPUNIT_API XmlDocument
{
public:
/*! \brief Constructs a XmlDocument object.
* \param encoding Encoding used in the XML file (default is Latin-1, ISO-8859-1 ).
* \param styleSheet Name of the XSL style sheet file used. If empty then no
* style sheet will be specified in the output.
*/
XmlDocument( const std::string &encoding = "",
const std::string &styleSheet = "" );
/// Destructor.
virtual ~XmlDocument();
std::string encoding() const;
void setEncoding( const std::string &encoding = "" );
std::string styleSheet() const;
void setStyleSheet( const std::string &styleSheet = "" );
bool standalone() const;
/*! \brief set the output document as standalone or not.
*
* For the output document, specify wether it's a standalone XML
* document, or not.
*
* \param standalone if true, the output will be specified as standalone.
* if false, it will be not.
*/
void setStandalone( bool standalone );
void setRootElement( XmlElement *rootElement );
XmlElement &rootElement() const;
std::string toString() const;
private:
/// Prevents the use of the copy constructor.
XmlDocument( const XmlDocument &copy );
/// Prevents the use of the copy operator.
void operator =( const XmlDocument &copy );
protected:
std::string m_encoding;
std::string m_styleSheet;
XmlElement *m_rootElement;
bool m_standalone;
};
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
CPPUNIT_NS_END
#endif // CPPUNIT_TOOLS_XMLDOCUMENT_H

View File

@@ -0,0 +1,149 @@
#ifndef CPPUNIT_TOOLS_XMLELEMENT_H
#define CPPUNIT_TOOLS_XMLELEMENT_H
#include <cppunit/Portability.h>
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( push )
#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
#endif
#include <cppunit/portability/CppUnitDeque.h>
#include <string>
CPPUNIT_NS_BEGIN
class XmlElement;
#if CPPUNIT_NEED_DLL_DECL
// template class CPPUNIT_API std::deque<XmlElement *>;
#endif
/*! \brief A XML Element.
*
* A XML element has:
* - a name, specified on construction,
* - a content, specified on construction (may be empty),
* - zero or more attributes, added with addAttribute(),
* - zero or more child elements, added with addElement().
*/
class CPPUNIT_API XmlElement
{
public:
/*! \brief Constructs an element with the specified name and string content.
* \param elementName Name of the element. Must not be empty.
* \param content Content of the element.
*/
XmlElement( std::string elementName,
std::string content ="" );
/*! \brief Constructs an element with the specified name and numeric content.
* \param elementName Name of the element. Must not be empty.
* \param numericContent Content of the element.
*/
XmlElement( std::string elementName,
int numericContent );
/*! \brief Destructs the element and its child elements.
*/
virtual ~XmlElement();
/*! \brief Returns the name of the element.
* \return Name of the element.
*/
std::string name() const;
/*! \brief Returns the content of the element.
* \return Content of the element.
*/
std::string content() const;
/*! \brief Sets the name of the element.
* \param name New name for the element.
*/
void setName( const std::string &name );
/*! \brief Sets the content of the element.
* \param content New content for the element.
*/
void setContent( const std::string &content );
/*! \overload void setContent( const std::string &content )
*/
void setContent( int numericContent );
/*! \brief Adds an attribute with the specified string value.
* \param attributeName Name of the attribute. Must not be an empty.
* \param value Value of the attribute.
*/
void addAttribute( std::string attributeName,
std::string value );
/*! \brief Adds an attribute with the specified numeric value.
* \param attributeName Name of the attribute. Must not be empty.
* \param numericValue Numeric value of the attribute.
*/
void addAttribute( std::string attributeName,
int numericValue );
/*! \brief Adds a child element to the element.
* \param element Child element to add. Must not be \c NULL.
*/
void addElement( XmlElement *element );
/*! \brief Returns the number of child elements.
* \return Number of child elements (element added with addElement()).
*/
int elementCount() const;
/*! \brief Returns the child element at the specified index.
* \param index Zero based index of the element to return.
* \returns Element at the specified index. Never \c NULL.
* \exception std::invalid_argument if \a index < 0 or index >= elementCount().
*/
XmlElement *elementAt( int index ) const;
/*! \brief Returns the first child element with the specified name.
* \param name Name of the child element to return.
* \return First child element found which is named \a name.
* \exception std::invalid_argument if there is no child element with the specified
* name.
*/
XmlElement *elementFor( const std::string &name ) const;
/*! \brief Returns a XML string that represents the element.
* \param indent String of spaces representing the amount of 'indent'.
* \return XML string that represents the element, its attributes and its
* child elements.
*/
std::string toString( const std::string &indent = "" ) const;
private:
typedef std::pair<std::string,std::string> Attribute;
std::string attributesAsString() const;
std::string escape( std::string value ) const;
private:
std::string m_name;
std::string m_content;
typedef CppUnitDeque<Attribute> Attributes;
Attributes m_attributes;
typedef CppUnitDeque<XmlElement *> Elements;
Elements m_elements;
};
CPPUNIT_NS_END
#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif
#endif // CPPUNIT_TOOLS_XMLELEMENT_H

View File

@@ -0,0 +1,24 @@
#ifndef CPPUNIT_UI_TEXT_TESTRUNNER_H
#define CPPUNIT_UI_TEXT_TESTRUNNER_H
#include <cppunit/ui/text/TextTestRunner.h>
#if defined(CPPUNIT_HAVE_NAMESPACES)
CPPUNIT_NS_BEGIN
namespace TextUi
{
/*! Text TestRunner (DEPRECATED).
* \deprecated Use TextTestRunner instead.
*/
typedef TextTestRunner TestRunner;
}
CPPUNIT_NS_END
#endif // defined(CPPUNIT_HAVE_NAMESPACES)
#endif // CPPUNIT_UI_TEXT_TESTRUNNER_H

View File

@@ -0,0 +1,97 @@
#ifndef CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H
#define CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H
#include <cppunit/Portability.h>
#include <string>
#include <cppunit/TestRunner.h>
CPPUNIT_NS_BEGIN
class Outputter;
class Test;
class TestSuite;
class TextOutputter;
class TestResult;
class TestResultCollector;
/*!
* \brief A text mode test runner.
* \ingroup WritingTestResult
* \ingroup ExecutingTest
*
* 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.
*
* TestRunner prints out a trace as the tests are executed followed by a
* summary at the end. The trace and summary print are optional.
*
* Here is an example of use:
*
* \code
* CppUnit::TextTestRunner runner;
* runner.addTest( ExampleTestCase::suite() );
* runner.run( "", true ); // Run all tests and wait
* \endcode
*
* The trace is printed using a TextTestProgressListener. The summary is printed
* using a TextOutputter.
*
* You can specify an alternate Outputter at construction
* or later with setOutputter().
*
* After construction, you can register additional TestListener to eventManager(),
* for a custom progress trace, for example.
*
* \code
* CppUnit::TextTestRunner runner;
* runner.addTest( ExampleTestCase::suite() );
* runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter(
* &runner.result(),
* std::cerr ) );
* MyCustomProgressTestListener progress;
* runner.eventManager().addListener( &progress );
* runner.run( "", true ); // Run all tests and wait
* \endcode
*
* \see CompilerOutputter, XmlOutputter, TextOutputter.
*/
class CPPUNIT_API TextTestRunner : public CPPUNIT_NS::TestRunner
{
public:
TextTestRunner( Outputter *outputter =NULL );
virtual ~TextTestRunner();
bool run( std::string testPath ="",
bool doWait = false,
bool doPrintResult = true,
bool doPrintProgress = true );
void setOutputter( Outputter *outputter );
TestResultCollector &result() const;
TestResult &eventManager() const;
public: // overridden from TestRunner (to avoid hidden virtual function warning)
virtual void run( TestResult &controller,
const std::string &testPath = "" );
protected:
virtual void wait( bool doWait );
virtual void printResult( bool doPrintResult );
TestResultCollector *m_result;
TestResult *m_eventManager;
Outputter *m_outputter;
};
CPPUNIT_NS_END
#endif // CPPUNIT_UI_TEXT_TEXTTESTRUNNER_H

View File

@@ -0,0 +1,41 @@
#include <cppunit/AdditionalMessage.h>
CPPUNIT_NS_BEGIN
AdditionalMessage::AdditionalMessage()
{
}
AdditionalMessage::AdditionalMessage( const std::string &detail1 )
{
if ( !detail1.empty() )
addDetail( detail1 );
}
AdditionalMessage::AdditionalMessage( const char *detail1 )
{
if ( detail1 && !std::string( detail1 ).empty() )
addDetail( std::string(detail1) );
}
AdditionalMessage::AdditionalMessage( const Message &other )
: SuperClass( other )
{
}
AdditionalMessage &
AdditionalMessage::operator =( const Message &other )
{
SuperClass::operator =( other );
return *this;
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,101 @@
#include <cppunit/Asserter.h>
#include <cppunit/Exception.h>
#include <cppunit/Message.h>
CPPUNIT_NS_BEGIN
void
Asserter::fail( std::string message,
const SourceLine &sourceLine )
{
fail( Message( "assertion failed", message ), sourceLine );
}
void
Asserter::fail( const Message &message,
const SourceLine &sourceLine )
{
throw Exception( message, sourceLine );
}
void
Asserter::failIf( bool shouldFail,
const Message &message,
const SourceLine &sourceLine )
{
if ( shouldFail )
fail( message, sourceLine );
}
void
Asserter::failIf( bool shouldFail,
std::string message,
const SourceLine &sourceLine )
{
failIf( shouldFail, Message( "assertion failed", message ), sourceLine );
}
std::string
Asserter::makeExpected( const std::string &expectedValue )
{
return "Expected: " + expectedValue;
}
std::string
Asserter::makeActual( const std::string &actualValue )
{
return "Actual : " + actualValue;
}
Message
Asserter::makeNotEqualMessage( const std::string &expectedValue,
const std::string &actualValue,
const AdditionalMessage &additionalMessage,
const std::string &shortDescription )
{
Message message( shortDescription,
makeExpected( expectedValue ),
makeActual( actualValue ) );
message.addDetail( additionalMessage );
return message;
}
void
Asserter::failNotEqual( std::string expected,
std::string actual,
const SourceLine &sourceLine,
const AdditionalMessage &additionalMessage,
std::string shortDescription )
{
fail( makeNotEqualMessage( expected,
actual,
additionalMessage,
shortDescription ),
sourceLine );
}
void
Asserter::failNotEqualIf( bool shouldFail,
std::string expected,
std::string actual,
const SourceLine &sourceLine,
const AdditionalMessage &additionalMessage,
std::string shortDescription )
{
if ( shouldFail )
failNotEqual( expected, actual, sourceLine, additionalMessage, shortDescription );
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,49 @@
#include <cppunit/Portability.h>
#if defined(CPPUNIT_HAVE_BEOS_DLL_LOADER)
#include <cppunit/plugin/DynamicLibraryManager.h>
#include <kernel/image.h>
CPPUNIT_NS_BEGIN
DynamicLibraryManager::LibraryHandle
DynamicLibraryManager::doLoadLibrary( const std::string &libraryName )
{
return (LibraryHandle)::load_add_on( libraryName.c_str() );
}
void
DynamicLibraryManager::doReleaseLibrary()
{
::unload_add_on( (image_id)m_libraryHandle );
}
DynamicLibraryManager::Symbol
DynamicLibraryManager::doFindSymbol( const std::string &symbol )
{
void *symbolPointer;
if ( ::get_image_symbol( (image_id)m_libraryHandle,
symbol.c_str(),
B_SYMBOL_TYPE_TEXT,
&symbolPointer ) == B_OK )
return symnolPointer;
return NULL;
}
std::string
DynamicLibraryManager::getLastErrorDetail() const
{
return "";
}
CPPUNIT_NS_END
#endif // defined(CPPUNIT_HAVE_BEOS_DLL_LOADER)

View File

@@ -0,0 +1,49 @@
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/Test.h>
#include <cppunit/TestFailure.h>
#include <cppunit/portability/Stream.h>
CPPUNIT_NS_BEGIN
BriefTestProgressListener::BriefTestProgressListener()
: m_lastTestFailed( false )
{
}
BriefTestProgressListener::~BriefTestProgressListener()
{
}
void
BriefTestProgressListener::startTest( Test *test )
{
stdCOut() << test->getName();
stdCOut().flush();
m_lastTestFailed = false;
}
void
BriefTestProgressListener::addFailure( const TestFailure &failure )
{
stdCOut() << " : " << (failure.isError() ? "error" : "assertion");
m_lastTestFailed = true;
}
void
BriefTestProgressListener::endTest( Test * )
{
if ( !m_lastTestFailed )
stdCOut() << " : OK";
stdCOut() << "\n";
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,216 @@
#include <cppunit/config/SourcePrefix.h>
#include <cppunit/Exception.h>
#include <cppunit/SourceLine.h>
#include <cppunit/TestFailure.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/CompilerOutputter.h>
#include <algorithm>
#include <cppunit/tools/StringTools.h>
CPPUNIT_NS_BEGIN
CompilerOutputter::CompilerOutputter( TestResultCollector *result,
OStream &stream,
const std::string &locationFormat )
: m_result( result )
, m_stream( stream )
, m_locationFormat( locationFormat )
, m_wrapColumn( CPPUNIT_WRAP_COLUMN )
{
}
CompilerOutputter::~CompilerOutputter()
{
}
void
CompilerOutputter::setLocationFormat( const std::string &locationFormat )
{
m_locationFormat = locationFormat;
}
CompilerOutputter *
CompilerOutputter::defaultOutputter( TestResultCollector *result,
OStream &stream )
{
return new CompilerOutputter( result, stream );
}
void
CompilerOutputter::write()
{
if ( m_result->wasSuccessful() )
printSuccess();
else
printFailureReport();
}
void
CompilerOutputter::printSuccess()
{
m_stream << "OK (" << m_result->runTests() << ")\n";
}
void
CompilerOutputter::printFailureReport()
{
printFailuresList();
printStatistics();
}
void
CompilerOutputter::printFailuresList()
{
for ( int index =0; index < m_result->testFailuresTotal(); ++index)
{
printFailureDetail( m_result->failures()[ index ] );
}
}
void
CompilerOutputter::printFailureDetail( TestFailure *failure )
{
printFailureLocation( failure->sourceLine() );
printFailureType( failure );
printFailedTestName( failure );
printFailureMessage( failure );
}
void
CompilerOutputter::printFailureLocation( SourceLine sourceLine )
{
if ( !sourceLine.isValid() )
{
m_stream << "##Failure Location unknown## : ";
return;
}
std::string location;
for ( unsigned int index = 0; index < m_locationFormat.length(); ++index )
{
char c = m_locationFormat[ index ];
if ( c == '%' && ( index+1 < m_locationFormat.length() ) )
{
char command = m_locationFormat[index+1];
if ( processLocationFormatCommand( command, sourceLine ) )
{
++index;
continue;
}
}
m_stream << c;
}
}
bool
CompilerOutputter::processLocationFormatCommand( char command,
const SourceLine &sourceLine )
{
switch ( command )
{
case 'p':
m_stream << sourceLine.fileName();
return true;
case 'l':
m_stream << sourceLine.lineNumber();
return true;
case 'f':
m_stream << extractBaseName( sourceLine.fileName() );
return true;
}
return false;
}
std::string
CompilerOutputter::extractBaseName( const std::string &fileName ) const
{
int indexLastDirectorySeparator = fileName.find_last_of( '/' );
if ( indexLastDirectorySeparator < 0 )
indexLastDirectorySeparator = fileName.find_last_of( '\\' );
if ( indexLastDirectorySeparator < 0 )
return fileName;
return fileName.substr( indexLastDirectorySeparator +1 );
}
void
CompilerOutputter::printFailureType( TestFailure *failure )
{
m_stream << (failure->isError() ? "Error" : "Assertion");
}
void
CompilerOutputter::printFailedTestName( TestFailure *failure )
{
m_stream << "\nTest name: " << failure->failedTestName();
}
void
CompilerOutputter::printFailureMessage( TestFailure *failure )
{
m_stream << "\n";
Exception *thrownException = failure->thrownException();
m_stream << thrownException->message().shortDescription() << "\n";
std::string message = thrownException->message().details();
if ( m_wrapColumn > 0 )
message = StringTools::wrap( message, m_wrapColumn );
m_stream << message << "\n";
}
void
CompilerOutputter::printStatistics()
{
m_stream << "Failures !!!\n";
m_stream << "Run: " << m_result->runTests() << " "
<< "Failure total: " << m_result->testFailuresTotal() << " "
<< "Failures: " << m_result->testFailures() << " "
<< "Errors: " << m_result->testErrors()
<< "\n";
}
void
CompilerOutputter::setWrapColumn( int wrapColumn )
{
m_wrapColumn = wrapColumn;
}
void
CompilerOutputter::setNoWrap()
{
m_wrapColumn = 0;
}
int
CompilerOutputter::wrapColumn() const
{
return m_wrapColumn;
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,42 @@
#include <cppunit/Exception.h>
#include <cppunit/extensions/TypeInfoHelper.h>
#include "DefaultProtector.h"
CPPUNIT_NS_BEGIN
bool
DefaultProtector::protect( const Functor &functor,
const ProtectorContext &context )
{
try
{
return functor();
}
catch ( Exception &failure )
{
reportFailure( context, failure );
}
catch ( std::exception &e )
{
std::string shortDescription( "uncaught exception of type " );
#if CPPUNIT_USE_TYPEINFO_NAME
shortDescription += TypeInfoHelper::getClassName( typeid(e) );
#else
shortDescription += "std::exception (or derived).";
#endif
Message message( shortDescription, e.what() );
reportError( context, message );
}
catch ( ... )
{
reportError( context,
Message( "uncaught exception of unknown type") );
}
return false;
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,27 @@
#ifndef CPPUNIT_DEFAULTPROTECTOR_H
#define CPPUNIT_DEFAULTPROTECTOR_H
#include <cppunit/Protector.h>
CPPUNIT_NS_BEGIN
/*! \brief Default protector that catch all exceptions (Implementation).
*
* Implementation detail.
* \internal This protector catch and generate a failure for the following
* exception types:
* - Exception
* - std::exception
* - ...
*/
class DefaultProtector : public Protector
{
public:
bool protect( const Functor &functor,
const ProtectorContext &context );
};
CPPUNIT_NS_END
#endif // CPPUNIT_DEFAULTPROTECTOR_H

View File

@@ -0,0 +1,16 @@
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOUSER
#define NOKERNEL
#define NOSOUND
#define BLENDFUNCTION void // for mingw & gcc
#include <windows.h>
BOOL APIENTRY
DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
return TRUE;
}

View File

@@ -0,0 +1,77 @@
#include <cppunit/plugin/DynamicLibraryManager.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <cppunit/plugin/DynamicLibraryManagerException.h>
CPPUNIT_NS_BEGIN
DynamicLibraryManager::DynamicLibraryManager( const std::string &libraryFileName )
: m_libraryHandle( NULL )
, m_libraryName( libraryFileName )
{
loadLibrary( libraryFileName );
}
DynamicLibraryManager::~DynamicLibraryManager()
{
releaseLibrary();
}
DynamicLibraryManager::Symbol
DynamicLibraryManager::findSymbol( const std::string &symbol )
{
try
{
Symbol symbolPointer = doFindSymbol( symbol );
if ( symbolPointer != NULL )
return symbolPointer;
}
catch ( ... )
{
}
throw DynamicLibraryManagerException( m_libraryName,
symbol,
DynamicLibraryManagerException::symbolNotFound );
return NULL; // keep compiler happy
}
void
DynamicLibraryManager::loadLibrary( const std::string &libraryName )
{
try
{
releaseLibrary();
m_libraryHandle = doLoadLibrary( libraryName );
if ( m_libraryHandle != NULL )
return;
}
catch (...)
{
}
throw DynamicLibraryManagerException( m_libraryName,
getLastErrorDetail(),
DynamicLibraryManagerException::loadingFailed );
}
void
DynamicLibraryManager::releaseLibrary()
{
if ( m_libraryHandle != NULL )
{
doReleaseLibrary();
m_libraryHandle = NULL;
}
}
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)

View File

@@ -0,0 +1,41 @@
#include <cppunit/plugin/DynamicLibraryManagerException.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
CPPUNIT_NS_BEGIN
DynamicLibraryManagerException::DynamicLibraryManagerException(
const std::string &libraryName,
const std::string &errorDetail,
Cause cause )
: std::runtime_error( "" ),
m_cause( cause )
{
if ( cause == loadingFailed )
m_message = "Failed to load dynamic library: " + libraryName + "\n" +
errorDetail;
else
m_message = "Symbol [" + errorDetail + "] not found in dynamic libary:" +
libraryName;
}
DynamicLibraryManagerException::Cause
DynamicLibraryManagerException::getCause() const
{
return m_cause;
}
const char *
DynamicLibraryManagerException::what() const throw()
{
return m_message.c_str();
}
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)

View File

@@ -0,0 +1,126 @@
#include <cppunit/Exception.h>
CPPUNIT_NS_BEGIN
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
/*!
* \deprecated Use SourceLine::isValid() instead.
*/
const std::string Exception::UNKNOWNFILENAME = "<unknown>";
/*!
* \deprecated Use SourceLine::isValid() instead.
*/
const long Exception::UNKNOWNLINENUMBER = -1;
#endif
Exception::Exception( const Exception &other )
: std::exception( other )
{
m_message = other.m_message;
m_sourceLine = other.m_sourceLine;
}
Exception::Exception( const Message &message,
const SourceLine &sourceLine )
: m_message( message )
, m_sourceLine( sourceLine )
{
}
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
Exception::Exception( std::string message,
long lineNumber,
std::string fileName )
: m_message( message )
, m_sourceLine( fileName, lineNumber )
{
}
#endif
Exception::~Exception() throw()
{
}
Exception &
Exception::operator =( const Exception& other )
{
// Don't call superclass operator =(). VC++ STL implementation
// has a bug. It calls the destructor and copy constructor of
// std::exception() which reset the virtual table to std::exception.
// SuperClass::operator =(other);
if ( &other != this )
{
m_message = other.m_message;
m_sourceLine = other.m_sourceLine;
}
return *this;
}
const char*
Exception::what() const throw()
{
Exception *mutableThis = CPPUNIT_CONST_CAST( Exception *, this );
mutableThis->m_whatMessage = m_message.shortDescription() + "\n" +
m_message.details();
return m_whatMessage.c_str();
}
SourceLine
Exception::sourceLine() const
{
return m_sourceLine;
}
Message
Exception::message() const
{
return m_message;
}
void
Exception::setMessage( const Message &message )
{
m_message = message;
}
#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
long
Exception::lineNumber() const
{
return m_sourceLine.isValid() ? m_sourceLine.lineNumber() :
UNKNOWNLINENUMBER;
}
std::string
Exception::fileName() const
{
return m_sourceLine.isValid() ? m_sourceLine.fileName() :
UNKNOWNFILENAME;
}
#endif
Exception *
Exception::clone() const
{
return new Exception( *this );
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,170 @@
#include <cppunit/Message.h>
#include <stdexcept>
CPPUNIT_NS_BEGIN
Message::Message()
{
}
Message::Message( const Message &other )
{
*this = other;
}
Message::Message( const std::string &shortDescription )
: m_shortDescription( shortDescription )
{
}
Message::Message( const std::string &shortDescription,
const std::string &detail1 )
: m_shortDescription( shortDescription )
{
addDetail( detail1 );
}
Message::Message( const std::string &shortDescription,
const std::string &detail1,
const std::string &detail2 )
: m_shortDescription( shortDescription )
{
addDetail( detail1, detail2 );
}
Message::Message( const std::string &shortDescription,
const std::string &detail1,
const std::string &detail2,
const std::string &detail3 )
: m_shortDescription( shortDescription )
{
addDetail( detail1, detail2, detail3 );
}
Message &
Message::operator =( const Message &other )
{
if ( this != &other )
{
m_shortDescription = other.m_shortDescription.c_str();
m_details.clear();
Details::const_iterator it = other.m_details.begin();
Details::const_iterator itEnd = other.m_details.end();
while ( it != itEnd )
m_details.push_back( (*it++).c_str() );
}
return *this;
}
const std::string &
Message::shortDescription() const
{
return m_shortDescription;
}
int
Message::detailCount() const
{
return m_details.size();
}
std::string
Message::detailAt( int index ) const
{
if ( index < 0 || index >= detailCount() )
throw std::invalid_argument( "Message::detailAt() : invalid index" );
return m_details[ index ];
}
std::string
Message::details() const
{
std::string details;
for ( Details::const_iterator it = m_details.begin(); it != m_details.end(); ++it )
{
details += "- ";
details += *it;
details += '\n';
}
return details;
}
void
Message::clearDetails()
{
m_details.clear();
}
void
Message::addDetail( const std::string &detail )
{
m_details.push_back( detail );
}
void
Message::addDetail( const std::string &detail1,
const std::string &detail2 )
{
addDetail( detail1 );
addDetail( detail2 );
}
void
Message::addDetail( const std::string &detail1,
const std::string &detail2,
const std::string &detail3 )
{
addDetail( detail1, detail2 );
addDetail( detail3 );
}
void
Message::addDetail( const Message &message )
{
m_details.insert( m_details.end(),
message.m_details.begin(),
message.m_details.end() );
}
void
Message::setShortDescription( const std::string &shortDescription )
{
m_shortDescription = shortDescription;
}
bool
Message::operator ==( const Message &other ) const
{
return m_shortDescription == other.m_shortDescription &&
m_details == other.m_details;
}
bool
Message::operator !=( const Message &other ) const
{
return !( *this == other );
}
CPPUNIT_NS_END

View File

@@ -0,0 +1,110 @@
#include <cppunit/config/SourcePrefix.h>
#include <cppunit/XmlOutputterHook.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/plugin/PlugInManager.h>
#include <cppunit/plugin/TestPlugIn.h>
#include <cppunit/plugin/DynamicLibraryManager.h>
CPPUNIT_NS_BEGIN
PlugInManager::PlugInManager()
{
}
PlugInManager::~PlugInManager()
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
unload( *it );
}
void
PlugInManager::load( const std::string &libraryFileName,
const PlugInParameters &parameters )
{
PlugInInfo info;
info.m_fileName = libraryFileName;
info.m_manager = new DynamicLibraryManager( libraryFileName );
TestPlugInSignature plug = (TestPlugInSignature)info.m_manager->findSymbol(
CPPUNIT_STRINGIZE( CPPUNIT_PLUGIN_EXPORTED_NAME ) );
info.m_interface = (*plug)();
m_plugIns.push_back( info );
info.m_interface->initialize( &TestFactoryRegistry::getRegistry(), parameters );
}
void
PlugInManager::unload( const std::string &libraryFileName )
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
{
if ( (*it).m_fileName == libraryFileName )
{
unload( *it );
m_plugIns.erase( it );
break;
}
}
}
void
PlugInManager::addListener( TestResult *eventManager )
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
(*it).m_interface->addListener( eventManager );
}
void
PlugInManager::removeListener( TestResult *eventManager )
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
(*it).m_interface->removeListener( eventManager );
}
void
PlugInManager::unload( PlugInInfo &plugIn )
{
try
{
plugIn.m_interface->uninitialize( &TestFactoryRegistry::getRegistry() );
delete plugIn.m_manager;
}
catch (...)
{
delete plugIn.m_manager;
plugIn.m_manager = NULL;
throw;
}
}
void
PlugInManager::addXmlOutputterHooks( XmlOutputter *outputter )
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
(*it).m_interface->addXmlOutputterHooks( outputter );
}
void
PlugInManager::removeXmlOutputterHooks()
{
for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it )
(*it).m_interface->removeXmlOutputterHooks();
}
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)

View File

@@ -0,0 +1,28 @@
#include <cppunit/plugin/PlugInParameters.h>
#if !defined(CPPUNIT_NO_TESTPLUGIN)
CPPUNIT_NS_BEGIN
PlugInParameters::PlugInParameters( const std::string &commandLine )
: m_commandLine( commandLine )
{
}
PlugInParameters::~PlugInParameters()
{
}
std::string
PlugInParameters::getCommandLine() const
{
return m_commandLine;
}
CPPUNIT_NS_END
#endif // !defined(CPPUNIT_NO_TESTPLUGIN)

Some files were not shown because too many files have changed in this diff Show More