Thread: [Cppunit-cvs] cppunit2/include/cpput assertcommon.h, 1.3, 1.4 assertenum.h, 1.12, 1.13 assertstring
Brought to you by:
blep
From: Baptiste L. <bl...@us...> - 2007-08-14 17:31:12
|
Update of /cvsroot/cppunit/cppunit2/include/cpput In directory sc8-pr-cvs4.sourceforge.net:/tmp/cvs-serv5281/include/cpput Modified Files: assertcommon.h assertenum.h assertstring.h forwards.h resource.h testinfo.h Log Message: Modified assertion implementation to force evaluation of user condition expression first, while preserving delegation to function, overloading and optional parameters feature. See CPPUT_BEGIN_ASSERTION_MACRO() documentation in testinfo.h for an example to update your custom assertion code. New implementation rely on operator evaluation order and operator overloading. The trick is documented in CPPUT_BEGIN_ASSERTION_MACRO(). Index: testinfo.h =================================================================== RCS file: /cvsroot/cppunit/cppunit2/include/cpput/testinfo.h,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** testinfo.h 13 Nov 2005 23:02:16 -0000 1.20 --- testinfo.h 14 Aug 2007 17:30:52 -0000 1.21 *************** *** 10,13 **** --- 10,14 ---- namespace CppUT { + /*! \brief Exception thrown when an aborting assertion fails. */ *************** *** 46,54 **** public: SourceLocation( const char *file = 0, ! unsigned int line =0, ! const char *function = 0 ) : file_( file ) , line_( line ) - , function_( function ) { } --- 47,53 ---- public: SourceLocation( const char *file = 0, ! unsigned int line =0 ) : file_( file ) , line_( line ) { } *************** *** 57,61 **** { file_ = 0; - function_ = 0; line_ = 0; } --- 56,59 ---- *************** *** 67,71 **** const char *file_; - const char *function_; unsigned int line_; }; --- 65,68 ---- *************** *** 166,169 **** --- 163,307 ---- + /// All checker functions used in assert and check macro should returns an object of this type. + class CheckerResult + { + public: + CheckerResult() + : status_( TestStatus::passed ) + , message_( "" ) + { + } + + void setFailed() + { + status_ = TestStatus::failed; + } + + /// Compose current result with another once. Used to chain checker functions. + /// If other status is skipped, then current status become skipped; + /// otherwise if other status is failed, then current status become failed; + /// otherwise current status remained unchanged. + /// \c other message is appended at the end of the current message. + void compose( const CheckerResult &other ) + { + switch ( status_ ) + { + case TestStatus::failed: + case TestStatus::passed: + if ( other.status_ != TestStatus::passed ) + status_ = other.status_; + break; + case TestStatus::skipped: + break; + default: + CPPTL_DEBUG_ASSERT_UNREACHABLE; + } + message_.extend( other.message_ ); + } + + TestStatus::Status status_; + Message message_; + }; + + namespace Impl { + + /// Implementation detail of CPPUT_BEGIN_ASSERTION_MACRO() & CPPUT_BEGIN_CHECKING_MACRO(). + class CheckerLineLocation + { + public: + const CheckerResult *result_; + unsigned long line_; + }; + + struct FileLocationMarker {}; + + + /// Implementation detail of CPPUT_BEGIN_ASSERTION_MACRO() & CPPUT_BEGIN_CHECKING_MACRO(). + class CheckerFileLocation + { + public: + const CheckerLineLocation *lineData_; + const char *file_; + }; + + /// Implementation detail of CPPUT_BEGIN_ASSERTION_MACRO() & CPPUT_BEGIN_CHECKING_MACRO(). + class AssertionTrigger + { + public: + static AssertionTrigger aborting; + static AssertionTrigger checking; + + AssertionTrigger &operator +=( const CheckerFileLocation &fileLocation ); + }; + + } // end of namespace Impl + + + /*! Starts an aborting assertion macro (throw an exception on assertion failure). + * \ingroup group_custom_assertions + * This macro provides the following properties for assertion: + * - condition is evaluated first to ease debugging of unit tests + * - assertion can take a variable number of parameters (typicaly an optional message). + * + * Typically, as little code as possible is put in assertion macro code to ease debugging. + * Usually, an assertion macro just start a function call: + * \code + * #define CPPUT_ASSERT_IS_EVEN \ + * CPPUT_BEGIN_ASSERTION_MACRO() checkIsEven + * #define CPPUT_ASSERT_IS_EVEN \ + * CPPUT_BEGIN_CHECKING_MACRO() checkIsEven + * + * CheckerResult checkIsEven( int x, const char *message = "" ) + * { + * CheckerResult result; + * if ( x % 2 != 0 ) + * { + * result.setFailed(); + * result.message_.add( message ); + * } + * return result; + * } + * void someTest() + * { + * CPPUT_CHECK_IS_EVEN( 1 ); + * CPPUT_CHECK_IS_EVEN( 2 ); + * } + * \endcode + * + * In the example above, both a checking and asserting macro have been implemented. The code to + * check the assertion is factorized in a single function than can take a variable number of parameters + * and be easily debugged. + * + * Implementation notes: + * + * This is achieved using a trick based on operator evaluation order described below: + * Basicaly an assertion has the following form: + * AssertionTrigger::aborting += __FILE__ + __LINE__ / checkCondition( condition expression ); + * For simplicity, we will use the following compact form for reference : + * x += f + l / checkCond( condition ); + * checkCond must returns an CheckerResult which as overloaded operator /. + * operator = evaluate right to left + * operator + evaluate left to right + * operator / evaluate left to right and as priority over +. + * So 'condition expression' is evaluted first, then checkCond(condition) is evaluated. + * Then 'l / checkCond(condition)' is evaluated, + * followed by f + l/ checkCond(condition) which yield to an CheckerFileLocation. Finally, + * x += f + l / checkCond( condition ) is evaluated, basically calling AssertionTrigger + * overloaded operator += with the final CheckerFileLocation that contains details about the assertion, + * as well as file/line location. + * \see CPPUT_BEGIN_CHECKING_MACRO. + */ + # define CPPUT_BEGIN_ASSERTION_MACRO() \ + CppUT::Impl::AssertionTrigger::aborting += (const CppUT::Impl::FileLocationMarker *)__FILE__ + __LINE__ / + + /*! Starts a checking assertion macro (continue test execution even on failure). + * \ingroup group_custom_assertions + * \see CPPUT_BEGIN_ASSERTION_MACRO() for example and implementation notes. + */ + # define CPPUT_BEGIN_CHECKING_MACRO() \ + CppUT::Impl::AssertionTrigger::checking += (const CppUT::Impl::FileLocationMarker *)__FILE__ + __LINE__ / + + + /*! \brief Provides notification of failed assertions and log events. */ *************** *** 248,259 **** TestStatus &testStatus(); ! void newAssertion( AssertionType type, ! const char *fileName, ! unsigned int lineNumber, ! const char *functionName = 0 ); ! ! Assertion ¤tAssertion(); ! ! void realizeAssertion(); void handleUnexpectedException( const Assertion &fault ); --- 386,393 ---- TestStatus &testStatus(); ! void handleAssertion( const char *file, ! unsigned int line, ! const CheckerResult &result, ! bool isAbortingAssertion ); void handleUnexpectedException( const Assertion &fault ); *************** *** 271,294 **** }; - /*! \brief Returns the current assertion. - * \ingroup group_custom_assertions - * \sa TestInfo - */ - Assertion &CPPUT_API currentAssertion(); - - /*! \brief Realizes the current assertion. - * \ingroup group_custom_assertions - * Pass the current assertion to the TestResultUpdater and set the test status to - * TestStatus::failed. - * - * If the current assertion type is abortingAssertion then an AbortingAssertionException - * is thrown. - * - * @exception AbortingAssertionException If assertionType was set to - * abortingAssertion. - * \sa TestInfo - */ - void CPPUT_API realizeAssertion(); - /*! \brief Log an event. * \sa TestInfo --- 405,408 ---- *************** *** 314,317 **** --- 428,449 ---- + inline CppUT::Impl::CheckerLineLocation operator /( unsigned long line, const CppUT::CheckerResult &result ) + { + CppUT::Impl::CheckerLineLocation lineData; + lineData.result_ = &result; + lineData.line_ = line; + return lineData; + } + + + inline CppUT::Impl::CheckerFileLocation operator +( const CppUT::Impl::FileLocationMarker *file, const CppUT::Impl::CheckerLineLocation &lineData ) + { + CppUT::Impl::CheckerFileLocation fileData; + fileData.file_ = (const char *)file; + fileData.lineData_ = &lineData; + return fileData; + } + + #endif // CPPUT_TESTINFO_H_INCLUDED Index: assertenum.h =================================================================== RCS file: /cvsroot/cppunit/cppunit2/include/cpput/assertenum.h,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** assertenum.h 13 Nov 2005 10:12:01 -0000 1.12 --- assertenum.h 14 Aug 2007 17:30:52 -0000 1.13 *************** *** 127,142 **** ,class ActualStringizer ,class EqualityPredicate> ! void checkCustomHeterogeneousSequenceEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ExpectedStringizer expectedStringizer, ! ActualStringizer actualStringizer, ! EqualityPredicate comparator, ! const Message &message ) { unsigned int diffIndex = Impl::getSequenceDiffIndex( expected, actual, comparator ); if ( diffIndex == Impl::noDifference ) ! return; typedef CppTL::SliceEnumerator<ExpectedEnumerator> ExpectedEnumeratorSlice; --- 127,143 ---- ,class ActualStringizer ,class EqualityPredicate> ! CheckerResult checkCustomHeterogeneousSequenceEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ExpectedStringizer expectedStringizer, ! ActualStringizer actualStringizer, ! EqualityPredicate comparator, ! const Message &message ) { + CheckerResult result; unsigned int diffIndex = Impl::getSequenceDiffIndex( expected, actual, comparator ); if ( diffIndex == Impl::noDifference ) ! return result; typedef CppTL::SliceEnumerator<ExpectedEnumerator> ExpectedEnumeratorSlice; *************** *** 146,160 **** ActualEnumeratorSlice actualDiff = CppTL::Enum::slice( actual, diffIndex ); ! Message newMessage( message ); ! newMessage.add( translate( "Sequences are not identical." ) ); ! newMessage.add( translate( "Divergence position (0 based): " ) + stringize(diffIndex) ); if ( common.is_open() ) ! newMessage.add( translate( "Common:\n" ) + enumToStringCustom(common, ! expectedStringizer) ); ! newMessage.add( translate( "Expected:\n" ) + enumToStringCustom(expectedDiff, ! expectedStringizer) ); ! newMessage.add( translate( "Actual:\n" ) + enumToStringCustom(actualDiff, ! actualStringizer) ); ! fail( newMessage ); } --- 147,162 ---- ActualEnumeratorSlice actualDiff = CppTL::Enum::slice( actual, diffIndex ); ! result.setFailed(); ! result.message_ = message; ! result.message_.add( translate( "Sequences are not identical." ) ); ! result.message_.add( translate( "Divergence position (0 based): " ) + stringize(diffIndex) ); if ( common.is_open() ) ! result.message_.add( translate( "Common:\n" ) + enumToStringCustom(common, ! expectedStringizer) ); ! result.message_.add( translate( "Expected:\n" ) + enumToStringCustom(expectedDiff, ! expectedStringizer) ); ! result.message_.add( translate( "Actual:\n" ) + enumToStringCustom(actualDiff, ! actualStringizer) ); ! return result; } *************** *** 162,174 **** ,class StringizerType ,class EqualityPredicate> ! void checkCustomSequenceEqual( const EnumeratorType &expected, ! const EnumeratorType &actual, ! StringizerType stringizer, ! EqualityPredicate comparator, ! const Message &message ) { ! checkCustomHeterogeneousSequenceEqual( expected, actual, ! stringizer, stringizer, ! comparator, message ); } --- 164,176 ---- ,class StringizerType ,class EqualityPredicate> ! CheckerResult checkCustomSequenceEqual( const EnumeratorType &expected, ! const EnumeratorType &actual, ! StringizerType stringizer, ! EqualityPredicate comparator, ! const Message &message ) { ! return checkCustomHeterogeneousSequenceEqual( expected, actual, ! stringizer, stringizer, ! comparator, message ); } *************** *** 176,189 **** ,class StringizerType ,class EqualityPredicate> ! void checkCustomStringSequenceEqual( const EnumeratorType &expected, ! const EnumeratorType &actual, ! StringizerType stringizer, ! const Message &message = Message() ) { typedef CPPTL_TYPENAME EnumeratorType::value_type ValueType; DefaultComparator<ValueType,ValueType> comparator; ! checkCustomHeterogeneousSequenceEqual( expected, actual, ! stringizer, stringizer, ! comparator, message ); } --- 178,191 ---- ,class StringizerType ,class EqualityPredicate> ! CheckerResult checkCustomStringSequenceEqual( const EnumeratorType &expected, ! const EnumeratorType &actual, ! StringizerType stringizer, ! const Message &message = Message() ) { typedef CPPTL_TYPENAME EnumeratorType::value_type ValueType; DefaultComparator<ValueType,ValueType> comparator; ! return checkCustomHeterogeneousSequenceEqual( expected, actual, ! stringizer, stringizer, ! comparator, message ); } *************** *** 191,204 **** ,class ActualEnumerator ,class EqualityPredicate> ! void checkCustomEqualitySequenceEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { typedef DefaultStringizer<CPPTL_TYPENAME ExpectedEnumerator::value_type> ExpectedStringizer; typedef DefaultStringizer<CPPTL_TYPENAME ActualEnumerator::value_type> ActualStringizer; ! checkCustomHeterogeneousSequenceEqual( expected, actual, ! ExpectedStringizer(), ActualStringizer(), ! comparator, message ); } --- 193,206 ---- ,class ActualEnumerator ,class EqualityPredicate> ! CheckerResult checkCustomEqualitySequenceEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { typedef DefaultStringizer<CPPTL_TYPENAME ExpectedEnumerator::value_type> ExpectedStringizer; typedef DefaultStringizer<CPPTL_TYPENAME ActualEnumerator::value_type> ActualStringizer; ! return checkCustomHeterogeneousSequenceEqual( expected, actual, ! ExpectedStringizer(), ActualStringizer(), ! comparator, message ); } *************** *** 206,216 **** template<class ExpectedEnumeratorType ,class ActualEnumeratorType> ! void checkSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumeratorType::value_type ,CPPTL_TYPENAME ActualEnumeratorType::value_type> comparator; ! checkCustomEqualitySequenceEqual( expected, actual, comparator, message ); } --- 208,218 ---- template<class ExpectedEnumeratorType ,class ActualEnumeratorType> ! CheckerResult checkSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumeratorType::value_type ,CPPTL_TYPENAME ActualEnumeratorType::value_type> comparator; ! return checkCustomEqualitySequenceEqual( expected, actual, comparator, message ); } *************** *** 218,240 **** ,class ActualEnumeratorType ,class EqualityPredicate> ! void checkCustomEqualityStlSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { ! checkCustomEqualitySequenceEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! comparator, message ); } template<class ExpectedEnumeratorType ,class ActualEnumeratorType> ! void checkStlSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! const Message &message = Message() ) { ! checkSequenceEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! message ); } --- 220,242 ---- ,class ActualEnumeratorType ,class EqualityPredicate> ! CheckerResult checkCustomEqualityStlSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { ! return checkCustomEqualitySequenceEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! comparator, message ); } template<class ExpectedEnumeratorType ,class ActualEnumeratorType> ! CheckerResult checkStlSequenceEqual( const ExpectedEnumeratorType &expected, ! const ActualEnumeratorType &actual, ! const Message &message = Message() ) { ! return checkSequenceEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! message ); } *************** *** 244,254 **** ,class ActualStringizer ,class EqualityPredicate> ! void checkCustomHeterogeneousSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ExpectedStringizer expectedStringizer, ! ActualStringizer actualStringizer, ! EqualityPredicate predicate, ! const Message &message ) { std::deque<CPPTL_TYPENAME ExpectedEnumerator::value_type> missing; std::deque<CPPTL_TYPENAME ActualEnumerator::value_type> extraneous; --- 246,257 ---- ,class ActualStringizer ,class EqualityPredicate> ! CheckerResult checkCustomHeterogeneousSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ExpectedStringizer expectedStringizer, ! ActualStringizer actualStringizer, ! EqualityPredicate predicate, ! const Message &message ) { + CheckerResult result; std::deque<CPPTL_TYPENAME ExpectedEnumerator::value_type> missing; std::deque<CPPTL_TYPENAME ActualEnumerator::value_type> extraneous; *************** *** 257,274 **** predicate ); if ( missing.empty() && extraneous.empty() ) ! return; ! Message newMessage( message ); ! newMessage.add( translate( "Sets do not contain the same items." ) ); ! newMessage.add( translate( "Actual:\n" ) + enumToStringCustom(actual,actualStringizer) ); if ( missing.size() > 0 ) ! newMessage.add( translate( "Missing:\n" ) + ! enumToStringCustom( CppTL::Enum::container(missing), ! expectedStringizer ) ); if ( extraneous.size() > 0 ) ! newMessage.add( translate( "Extraneous:\n" ) + ! enumToStringCustom( CppTL::Enum::container(extraneous), ! actualStringizer ) ); ! fail( newMessage ); } --- 260,278 ---- predicate ); if ( missing.empty() && extraneous.empty() ) ! return result; ! result.setFailed(); ! result.message_ = message; ! result.message_.add( translate( "Sets do not contain the same items." ) ); ! result.message_.add( translate( "Actual:\n" ) + enumToStringCustom(actual,actualStringizer) ); if ( missing.size() > 0 ) ! result.message_.add( translate( "Missing:\n" ) + ! enumToStringCustom( CppTL::Enum::container(missing), ! expectedStringizer ) ); if ( extraneous.size() > 0 ) ! result.message_.add( translate( "Extraneous:\n" ) + ! enumToStringCustom( CppTL::Enum::container(extraneous), ! actualStringizer ) ); ! return result; } *************** *** 277,289 **** ,class ItemStringizer ,class EqualityPredicate> ! void checkCustomSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ItemStringizer itemStringizer, ! EqualityPredicate comparator, ! const Message &message = Message() ) { ! checkCustomHeterogeneousSetEqual( expected, actual, ! itemStringizer, itemStringizer, ! comparator, message ); } --- 281,293 ---- ,class ItemStringizer ,class EqualityPredicate> ! CheckerResult checkCustomSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ItemStringizer itemStringizer, ! EqualityPredicate comparator, ! const Message &message = Message() ) { ! return checkCustomHeterogeneousSetEqual( expected, actual, ! itemStringizer, itemStringizer, ! comparator, message ); } *************** *** 291,302 **** ,class ActualEnumerator ,class ItemStringizer> ! void checkCustomStringSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ItemStringizer itemStringizer, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumerator::value_type ,CPPTL_TYPENAME ActualEnumerator::value_type> comparator; ! checkCustomSetEqual( expected, actual, itemStringizer, comparator, message ); } --- 295,306 ---- ,class ActualEnumerator ,class ItemStringizer> ! CheckerResult checkCustomStringSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! ItemStringizer itemStringizer, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumerator::value_type ,CPPTL_TYPENAME ActualEnumerator::value_type> comparator; ! return checkCustomSetEqual( expected, actual, itemStringizer, comparator, message ); } *************** *** 304,339 **** ,class ActualEnumerator ,class EqualityPredicate> ! void checkCustomEqualitySetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { typedef DefaultStringizer<CPPTL_TYPENAME ExpectedEnumerator::value_type> ExpectedStringizer; typedef DefaultStringizer<CPPTL_TYPENAME ActualEnumerator::value_type> ActualStringizer; ! checkCustomHeterogeneousSetEqual( expected, actual, ! ExpectedStringizer(), ActualStringizer(), ! comparator, message ); } template<class ExpectedEnumerator ,class ActualEnumerator> ! void checkSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumerator::value_type ,CPPTL_TYPENAME ActualEnumerator::value_type> comparator; ! checkCustomEqualitySetEqual( expected, actual, comparator, message ); } template<class ExpectedStlSet ,class ActualStlSet> ! void checkStlSetEqual( const ExpectedStlSet &expected, ! const ActualStlSet &actual, ! const Message &message = Message() ) { ! checkSetEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! message ); } --- 308,343 ---- ,class ActualEnumerator ,class EqualityPredicate> ! CheckerResult checkCustomEqualitySetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! EqualityPredicate comparator, ! const Message &message = Message() ) { typedef DefaultStringizer<CPPTL_TYPENAME ExpectedEnumerator::value_type> ExpectedStringizer; typedef DefaultStringizer<CPPTL_TYPENAME ActualEnumerator::value_type> ActualStringizer; ! return checkCustomHeterogeneousSetEqual( expected, actual, ! ExpectedStringizer(), ActualStringizer(), ! comparator, message ); } template<class ExpectedEnumerator ,class ActualEnumerator> ! CheckerResult checkSetEqual( const ExpectedEnumerator &expected, ! const ActualEnumerator &actual, ! const Message &message = Message() ) { DefaultComparator<CPPTL_TYPENAME ExpectedEnumerator::value_type ,CPPTL_TYPENAME ActualEnumerator::value_type> comparator; ! return checkCustomEqualitySetEqual( expected, actual, comparator, message ); } template<class ExpectedStlSet ,class ActualStlSet> ! CheckerResult checkStlSetEqual( const ExpectedStlSet &expected, ! const ActualStlSet &actual, ! const Message &message = Message() ) { ! return checkSetEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! message ); } *************** *** 341,352 **** ,class ActualSetType ,class EqualityPredicate> ! void checkCustomEqualityStlSetEqual( const ExpectedSetType &expected, ! const ActualSetType &actual, ! EqualityPredicate predicate, ! const Message &message = Message() ) { ! checkSetEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! predicate, message ); } --- 345,356 ---- ,class ActualSetType ,class EqualityPredicate> ! CheckerResult checkCustomEqualityStlSetEqual( const ExpectedSetType &expected, ! const ActualSetType &actual, ! EqualityPredicate predicate, ! const Message &message = Message() ) { ! return checkSetEqual( CppTL::Enum::container( expected ), ! CppTL::Enum::container( actual ), ! predicate, message ); } Index: forwards.h =================================================================== RCS file: /cvsroot/cppunit/cppunit2/include/cpput/forwards.h,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** forwards.h 8 Nov 2005 21:50:33 -0000 1.20 --- forwards.h 14 Aug 2007 17:30:52 -0000 1.21 *************** *** 18,26 **** class ExceptionGuardElement; class ExceptionGuard; - class TestInfo; - class TestResultUpdater; class TestSuite; class TestVisitor; typedef CppTL::IntrusivePtr<AbstractTestCase> AbstractTestCasePtr; typedef CppTL::IntrusivePtr<AbstractTestSuite> AbstractTestSuitePtr; --- 18,29 ---- class ExceptionGuardElement; class ExceptionGuard; class TestSuite; class TestVisitor; + // testinfo.h + class CheckerResult; + class TestInfo; + class TestResultUpdater; + typedef CppTL::IntrusivePtr<AbstractTestCase> AbstractTestCasePtr; typedef CppTL::IntrusivePtr<AbstractTestSuite> AbstractTestSuitePtr; Index: assertcommon.h =================================================================== RCS file: /cvsroot/cppunit/cppunit2/include/cpput/assertcommon.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** assertcommon.h 2 Sep 2006 11:24:53 -0000 1.3 --- assertcommon.h 14 Aug 2007 17:30:52 -0000 1.4 *************** *** 11,44 **** namespace CppUT { ! void CPPUT_API fail(); ! ! void CPPUT_API fail( const LazyMessage &message ); ! void CPPUT_API checkTrue( bool shouldBeTrue, ! const LazyMessage &message = LazyMessage::none ); ! void CPPUT_API checkFalse( bool shouldBeFalse, ! const LazyMessage &message = LazyMessage::none ); ! void CPPUT_API checkAssertionFail( bool assertionFailed, const LazyMessage &message = LazyMessage::none ); ! void CPPUT_API checkAssertionPass( bool assertionFailed, ! const LazyMessage &message = LazyMessage::none ); ! Message CPPUT_API buildEqualityFailedMessage( const std::string &expected, ! const std::string &actual, ! const LazyMessage &message = LazyMessage::none ); template<typename FirstType ,typename SecondType> ! Message makeEqualityFailedMessage( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { std::string strExpected = stringize( expected ); std::string strActual = stringize( actual ); ! return buildEqualityFailedMessage( strExpected, strActual, message ); } --- 11,48 ---- namespace CppUT { ! CheckerResult CPPUT_API pass(); ! CheckerResult CPPUT_API fail(); ! CheckerResult CPPUT_API fail( const LazyMessage &message ); ! CheckerResult CPPUT_API checkTrue( bool shouldBeTrue, const LazyMessage &message = LazyMessage::none ); ! CheckerResult CPPUT_API checkFalse( bool shouldBeFalse, ! const LazyMessage &message = LazyMessage::none ); ! CheckerResult CPPUT_API checkAssertionFail( bool assertionFailed, ! const LazyMessage &message = LazyMessage::none ); ! ! CheckerResult CPPUT_API checkAssertionPass( bool assertionFailed, ! const LazyMessage &message = LazyMessage::none ); ! ! void CPPUT_API buildEqualityFailedMessage( CheckerResult &result, ! const std::string &expected, ! const std::string &actual, ! const LazyMessage &message = LazyMessage::none ); template<typename FirstType ,typename SecondType> ! void makeEqualityFailedMessage( CheckerResult &result, ! const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { std::string strExpected = stringize( expected ); std::string strActual = stringize( actual ); ! buildEqualityFailedMessage( result, strExpected, strActual, message ); } *************** *** 46,86 **** ,typename SecondType ,typename EqualityFunctorType> ! void checkEquals( const FirstType &expected, ! const SecondType &actual, ! EqualityFunctorType equality, ! const Message &message ) { ! if ( equality( expected, actual ) ) ! return; ! ! fail( makeEqualityFailedMessage( expected, actual, message ) ); } template<typename FirstType ,typename SecondType> ! void checkEquals( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { ! if ( equalityTest( expected, actual ) ) ! return; ! ! fail( makeEqualityFailedMessage( expected, actual, message ) ); } ! Message CPPUT_API buildUnequalityFailedMessage( const std::string &expected, ! const std::string &actual, ! const LazyMessage &message = LazyMessage::none ); template<typename FirstType ,typename SecondType> ! Message makeUnequalityFailedMessage( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { std::string strExpected = stringize( expected ); std::string strActual = stringize( actual ); ! return buildUnequalityFailedMessage( strExpected, strActual, message ); } --- 50,92 ---- ,typename SecondType ,typename EqualityFunctorType> ! CheckerResult checkEquals( const FirstType &expected, ! const SecondType &actual, ! EqualityFunctorType equality, ! const Message &message ) { ! CheckerResult result; ! if ( !equality( expected, actual ) ) ! makeEqualityFailedMessage( result, expected, actual, message ); ! return result; } template<typename FirstType ,typename SecondType> ! CheckerResult checkEquals( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { ! CheckerResult result; ! if ( !equalityTest( expected, actual ) ) ! makeEqualityFailedMessage( result, expected, actual, message ); ! return result; } ! void CPPUT_API buildUnequalityFailedMessage( CheckerResult &result, ! const std::string &expected, ! const std::string &actual, ! const LazyMessage &message = LazyMessage::none ); template<typename FirstType ,typename SecondType> ! void makeUnequalityFailedMessage( CheckerResult &result, ! const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { std::string strExpected = stringize( expected ); std::string strActual = stringize( actual ); ! buildUnequalityFailedMessage( result, strExpected, strActual, message ); } *************** *** 88,118 **** ,typename SecondType ,typename EqualityFunctorType> ! void checkNotEquals( const FirstType &expected, ! const SecondType &actual, ! EqualityFunctorType equality, ! const Message &message ) { ! if ( !( equality( expected, actual ) ) ) ! return; ! ! fail( makeUnequalityFailedMessage( expected, actual, message ) ); } template<typename FirstType ,typename SecondType> ! void checkNotEquals( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { ! if ( !( equalityTest( expected, actual ) ) ) ! return; ! ! fail( makeUnequalityFailedMessage( expected, actual, message ) ); } ! void CPPUT_API checkDoubleEquals( double expected, ! double actual, ! double tolerance, ! const LazyMessage &message = LazyMessage::none ); void CPPUT_API skipCurrentTest(); --- 94,124 ---- ,typename SecondType ,typename EqualityFunctorType> ! CheckerResult checkNotEquals( const FirstType &expected, ! const SecondType &actual, ! EqualityFunctorType equality, ! const Message &message ) { ! CheckerResult result; ! if ( equality( expected, actual ) ) ! makeUnequalityFailedMessage( result, expected, actual, message ); ! return result; } template<typename FirstType ,typename SecondType> ! CheckerResult checkNotEquals( const FirstType &expected, ! const SecondType &actual, ! const LazyMessage &message = LazyMessage::none ) { ! CheckerResult result; ! if ( equalityTest( expected, actual ) ) ! makeUnequalityFailedMessage( result, expected, actual, message ); ! return result; } ! CheckerResult CPPUT_API checkDoubleEquals( double expected, ! double actual, ! double tolerance, ! const LazyMessage &message = LazyMessage::none ); void CPPUT_API skipCurrentTest(); *************** *** 121,152 **** - /*! Starts either an aborting assertion or a checking assertion macro. - * \ingroup group_custom_assertions - * \internal - * __func__ should contains the current fonction name on many compiler (C99 compiler extension). See: - * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.vacpp7a.doc/language/ref/clrc02predefined_identifiers.htm - * Available if __C99__FUNC__ is defined: - * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.vacpp7a.doc/language/ref/clrapxaix_macros.htm - */ - # define CPPUT_CHECK_POINT( assertionType ) \ - ::CppUT::TestInfo::threadInstance().newAssertion( ::CppUT::assertionType, \ - __FILE__, \ - __LINE__ ) - /*! Starts an aborting assertion macro. - * \ingroup group_custom_assertions - */ - # define CPPUT_BEGIN_ASSERTION_MACRO() \ - CPPUT_CHECK_POINT( abortingAssertion ), - - /*! Starts a checking assertion macro. - * \ingroup group_custom_assertions - */ - # define CPPUT_BEGIN_CHECKING_MACRO() \ - CPPUT_CHECK_POINT( checkingAssertion ), - // basic assertions ! /*! \brief Always fails with the given message. * \ingroup group_assertions * \see CppUT::fail --- 127,134 ---- // basic assertions ! /*! \brief Always fails and abort current test with the given message. * \ingroup group_assertions * \see CppUT::fail *************** *** 156,159 **** --- 138,159 ---- ::CppUT::fail + /*! \brief Always fails with the given message, but continue current test. + * \ingroup group_assertions + * \see CppUT::fail + */ + # define CPPUT_CHECKING_FAIL \ + CPPUT_BEGIN_CHECKING_MACRO() \ + ::CppUT::fail + + /*! \brief Always succeed. Only used for succeed branch of a fail/pass assertion. + * \ingroup group_assertions + * This is required to increase the assertion count made in the test, in the case + * policy such as 'test fails in no assertion are done.' + */ + # define CPPUT_PASS \ + CPPUT_BEGIN_CHECKING_MACRO() \ + ::CppUT::pass + + /*! \brief Asserts that an expression evaluate to true. * \ingroup group_assertions *************** *** 277,297 **** /*! \internal */ ! # define _CPPUT_ASSERT_THROW_IMPL( assertionType, expression, ExceptionType ) \ ! do { \ ! CPPUT_CHECK_POINT( assertionType ); \ ! bool cpputExceptionThrown_ = false; \ ! try { \ ! expression; \ ! } catch ( const ExceptionType & ) { \ ! cpputExceptionThrown_ = true; \ ! } \ ! \ ! if ( cpputExceptionThrown_ ) \ ! break; \ ! \ ! ::CppUT::fail( "Expected exception: " #ExceptionType \ ! " not thrown." ); \ ! } while ( false ) --- 277,299 ---- /*! \internal + * @todo catch other unexpected exception. Use generic get exception type handler. + * Implementation notes: we need to call the failMacro outside the try/catch to + * ensure the AbortingAssertionException is not caught by the catch clause. */ ! # define _CPPUT_ASSERT_THROW_IMPL( failMacro, expression, ExceptionType ) \ ! try { \ ! bool noExceptionThrown = true; \ ! try { \ ! expression; \ ! } catch ( const ExceptionType & ) { \ ! CPPUT_PASS(); \ ! noExceptionThrown = false; \ ! } \ ! if ( noExceptionThrown ) \ ! failMacro( "Expected exception: " #ExceptionType \ ! " not thrown." ); \ ! } catch ( ... ) { /* catch like do while(false), but avoid warning */ \ ! throw; \ ! } *************** *** 300,304 **** */ # define CPPUT_ASSERT_THROW( expression, ExceptionType ) \ ! _CPPUT_ASSERT_THROW_IMPL( abortingAssertion, expression, ExceptionType ) /*! \brief Checks that an expression throw an exception of a specified type --- 302,306 ---- */ # define CPPUT_ASSERT_THROW( expression, ExceptionType ) \ ! _CPPUT_ASSERT_THROW_IMPL( CPPUT_FAIL, expression, ExceptionType ) /*! \brief Checks that an expression throw an exception of a specified type *************** *** 306,316 **** */ # define CPPUT_CHECK_THROW( expression, ExceptionType ) \ ! _CPPUT_CHECK_THROW_IMPL( checkingAssertion, expression, ExceptionType ) /*! \internal */ ! # define _CPPUT_ASSERT_NO_THROW_IMPL( assertionType, expression ) \ try { \ - CPPUT_CHECK_POINT( assertionType ); \ expression; \ } catch ( const std::exception &e ) { \ --- 308,318 ---- */ # define CPPUT_CHECK_THROW( expression, ExceptionType ) \ ! _CPPUT_CHECK_THROW_IMPL( CPPUT_CHECKING_FAIL, expression, ExceptionType ) /*! \internal + * @todo replace with generic exception handler to get type & data. */ ! # define _CPPUT_ASSERT_NO_THROW_IMPL( failMacro, expression ) \ try { \ expression; \ } catch ( const std::exception &e ) { \ *************** *** 318,325 **** message.add( "Type: " + \ ::CppTL::getObjectTypeName( e, "std::exception" ) ); \ ! message.add( std::string("What: ") + e.what() ); \ ! ::CppUT::fail( message ); \ } catch ( ... ) { \ ! ::CppUT::fail( "Unexpected exception caught" ); \ } --- 320,327 ---- message.add( "Type: " + \ ::CppTL::getObjectTypeName( e, "std::exception" ) ); \ ! message.add( std::string("What: ") + e.what() ); \ ! failMacro( message ); \ } catch ( ... ) { \ ! failMacro( "Unexpected exception caught" ); \ } *************** *** 329,333 **** */ # define CPPUT_ASSERT_NO_THROW( expression ) \ ! _CPPUT_ASSERT_NO_THROW_IMPL( abortingAssertion, expression ) /*! \brief Checks that an expression does not throw any exception --- 331,335 ---- */ # define CPPUT_ASSERT_NO_THROW( expression ) \ ! _CPPUT_ASSERT_NO_THROW_IMPL( CPPUT_FAIL, expression ) /*! \brief Checks that an expression does not throw any exception *************** *** 335,339 **** */ # define CPPUT_CHECK_NO_THROW( expression ) \ ! _CPPUT_ASSERT_NO_THROW_IMPL( checkingAssertion, expression ) --- 337,341 ---- */ # define CPPUT_CHECK_NO_THROW( expression ) \ ! _CPPUT_ASSERT_NO_THROW_IMPL( CPPUT_CHECKING_FAIL, expression ) *************** *** 348,354 **** * properties are captured for later inspection. */ ! # define _CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE_IMPL( assertionType, assertion, message ) \ { \ - CPPUT_CHECK_POINT( assertionType ); \ bool assertionFailedCppUT_ = false; \ { \ --- 350,355 ---- * properties are captured for later inspection. */ ! # define _CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE_IMPL( beginMacro, assertion, message ) \ { \ bool assertionFailedCppUT_ = false; \ { \ *************** *** 360,364 **** assertionFailedCppUT_ = ::CppUT::TestInfo::threadInstance().testStatus().hasFailed(); \ } \ ! ::CppUT::checkAssertionFail( assertionFailedCppUT_, message ); \ } --- 361,365 ---- assertionFailedCppUT_ = ::CppUT::TestInfo::threadInstance().testStatus().hasFailed(); \ } \ ! beginMacro() ::CppUT::checkAssertionFail( assertionFailedCppUT_, message ); \ } *************** *** 367,371 **** */ # define CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE( assertion, message ) \ ! _CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE_IMPL( abortingAssertion, assertion, message ) /*! \brief Checks that an assertion fails (for use to unit test custom assertion) --- 368,372 ---- */ # define CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE( assertion, message ) \ ! _CPPUT_ASSERT_ASSERTION_FAIL_MESSAGE_IMPL( CPPUT_BEGIN_ASSERTION_MACRO, assertion, message ) /*! \brief Checks that an assertion fails (for use to unit test custom assertion) *************** *** 373,377 **** */ # define CPPUT_CHECK_ASSERTION_FAIL_MESSAGE( assertion, message ) \ ! _CPPUT_CHECK_ASSERTION_FAIL_MESSAGE_IMPL( checkingAssertion, assertion, message ) /*! \brief Asserts that an assertion fails (for use to unit test custom assertion) --- 374,378 ---- */ # define CPPUT_CHECK_ASSERTION_FAIL_MESSAGE( assertion, message ) \ ! _CPPUT_CHECK_ASSERTION_FAIL_MESSAGE_IMPL( CPPUT_BEGIN_CHECKING_MACRO, assertion, message ) /*! \brief Asserts that an assertion fails (for use to unit test custom assertion) *************** *** 389,395 **** /*! \internal */ ! # define _CPPUT_ASSERT_ASSERTION_PASS_MESSAGE_IMPL( assertionType, assertion, message ) \ { \ - CPPUT_CHECK_POINT( assertionType ); \ bool assertionFailedCppUT_ = false; \ { \ --- 390,395 ---- /*! \internal */ ! # define _CPPUT_ASSERT_ASSERTION_PASS_MESSAGE_IMPL( beginMacro, assertion, message ) \ { \ bool assertionFailedCppUT_ = false; \ { \ *************** *** 401,405 **** assertionFailedCppUT_ = ::CppUT::TestInfo::threadInstance().testStatus().hasFailed(); \ } \ ! ::CppUT::checkAssertionPass( assertionFailedCppUT_, message ); \ } --- 401,405 ---- assertionFailedCppUT_ = ::CppUT::TestInfo::threadInstance().testStatus().hasFailed(); \ } \ ! beginMacro() ::CppUT::checkAssertionPass( assertionFailedCppUT_, message ); \ } *************** *** 409,413 **** */ # define CPPUT_ASSERT_ASSERTION_PASS_MESSAGE( assertion, message ) \ ! _CPPUT_ASSERT_ASSERTION_PASS_MESSAGE_IMPL( abortingAssertion, assertion, message ) --- 409,413 ---- */ # define CPPUT_ASSERT_ASSERTION_PASS_MESSAGE( assertion, message ) \ ! _CPPUT_ASSERT_ASSERTION_PASS_MESSAGE_IMPL( CPPUT_BEGIN_ASSERTION_MACRO, assertion, message ) *************** *** 416,420 **** */ # define CPPUT_CHECK_ASSERTION_PASS_MESSAGE( assertion, message ) \ ! _CPPUT_CHECK_ASSERTION_PASS_MESSAGE_IMPL( checkingAssertion, assertion, message ) --- 416,420 ---- */ # define CPPUT_CHECK_ASSERTION_PASS_MESSAGE( assertion, message ) \ ! _CPPUT_CHECK_ASSERTION_PASS_MESSAGE_IMPL( CPPUT_BEGIN_CHECKING_MACRO, assertion, message ) *************** *** 431,435 **** CPPUT_CHECK_ASSERTION_PASS_MESSAGE( assertion, ::CppUT::Message() ) ! /*! \brief Skips and aborts the current test. * \ingroup group_assertions * --- 431,435 ---- CPPUT_CHECK_ASSERTION_PASS_MESSAGE( assertion, ::CppUT::Message() ) ! /*! \brief Skips the current test (test is aborted via thrown exception). * \ingroup group_assertions * *************** *** 456,464 **** * * \warning Be sure to always use <b>double braces</b> around the macro parameter to avoid ! * preprocessor mess. */ # define CPPUT_IGNORE_FAILURE( assertion ) \ { \ - CPPUT_CHECK_POINT( checkingAssertion ); \ bool failedCppUT_; \ { \ --- 456,463 ---- * * \warning Be sure to always use <b>double braces</b> around the macro parameter to avoid ! * preprocessor mess and portability issues. */ # define CPPUT_IGNORE_FAILURE( assertion ) \ { \ bool failedCppUT_; \ { \ *************** *** 469,472 **** --- 468,472 ---- } \ } \ + CPPUT_BEGIN_CHECKING_MACRO() \ ::CppUT::checkAssertionFail( failedCppUT_, #assertion ); \ } Index: assertstring.h =================================================================== RCS file: /cvsroot/cppunit/cppunit2/include/cpput/assertstring.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** assertstring.h 13 Nov 2005 10:12:01 -0000 1.5 --- assertstring.h 14 Aug 2007 17:30:52 -0000 1.6 *************** *** 6,56 **** namespace CppUT { ! void CPPUT_API checkStdStringStartsWith( const std::string &string, ! const std::string &pattern, ! const Message &message ); ! void CPPUT_API checkStdStringEndsWith( const std::string &string, ! const std::string &pattern, ! const Message &message ); ! void CPPUT_API checkStdStringContains( const std::string &str... [truncated message content] |