diff --git a/approvalTests.py b/approvalTests.py index b0bf4845..c6ede479 100644 --- a/approvalTests.py +++ b/approvalTests.py @@ -11,7 +11,10 @@ baselinesPath = os.path.join( catchPath, 'projects/SelfTest/Baselines/approvedRe rawResultsPath = os.path.join( catchPath, 'projects/SelfTest/Baselines/_rawResults.tmp' ) filteredResultsPath = os.path.join( catchPath, 'projects/SelfTest/Baselines/unapprovedResults.txt' ) -cmdPath = sys.argv[1] +if len(sys.argv) == 2: + cmdPath = sys.argv[1] +else: + cmdPath = "projects/XCode4/CatchSelfTest/DerivedData/CatchSelfTest/Build/Products/Debug/CatchSelfTest" f = open( rawResultsPath, 'w' ) subprocess.call([ cmdPath, "~dummy", "-s", "-w", "NoAssertions", "-r", "console" ], stdout=f, stderr=f ) diff --git a/include/catch.hpp b/include/catch.hpp index 6fb0fd10..2519ebf6 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -68,12 +68,12 @@ #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) -#define CATCH_INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CATCH_INFO" ) +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN" ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL" ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED" ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "CATCH_SCOPED_INFO" ) -#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CAPTURE" ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "CATCH_SCOPED_CAPTURE" ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) @@ -111,12 +111,12 @@ #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) -#define INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "INFO" ) +#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) #define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN" ) #define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL" ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED" ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "SCOPED_INFO" ) -#define CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CAPTURE" ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "SCOPED_CAPTURE" ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index e2919848..a32528a9 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -10,6 +10,7 @@ #include "catch_expression_decomposer.hpp" #include "catch_expressionresult_builder.h" +#include "catch_message.h" #include "catch_interfaces_capture.h" #include "catch_debugger.hpp" #include "catch_context.h" @@ -54,26 +55,6 @@ namespace Catch { struct TestFailureException{}; -class ScopedInfo { -public: - ScopedInfo() : m_resultBuilder( ResultWas::Info ) { - getResultCapture().pushScopedInfo( this ); - } - ~ScopedInfo() { - getResultCapture().popScopedInfo( this ); - } - template - ScopedInfo& operator << ( const T& value ) { - m_resultBuilder << value; - return *this; - } - AssertionResult buildResult( const AssertionInfo& assertionInfo ) const { - return m_resultBuilder.buildResult( assertionInfo ); - } - -private: - ExpressionResultBuilder m_resultBuilder; -}; // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool isTrue( bool value ){ return value; } @@ -168,17 +149,24 @@ inline bool isTrue( bool value ){ return value; } } while( Catch::isTrue( false ) ) /////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_MSG( reason, resultType, resultDisposition, macroName ) \ +#define INTERNAL_CATCH_INFO( log, macroName ) \ + do { \ + Catch::getResultCapture().acceptMessage( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); \ + } while( Catch::isTrue( false ) ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG( log, messageType, resultDisposition, macroName ) \ do { \ INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \ - INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( resultType ) << reason, resultDisposition, true ) \ + INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << log, resultDisposition, true ) \ } while( Catch::isTrue( false ) ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_SCOPED_INFO( log, macroName ) \ - INTERNAL_CATCH_ACCEPT_INFO( "", macroName, Catch::ResultDisposition::Normal ); \ - Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \ - INTERNAL_CATCH_UNIQUE_NAME( info ) << log + Catch::ScopedMessageBuilder INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ); \ + INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) << log; \ + Catch::getResultCapture().pushScopedMessage( INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) ) + /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp index 660cbffe..f95eaca8 100644 --- a/include/internal/catch_commandline.hpp +++ b/include/internal/catch_commandline.hpp @@ -148,7 +148,7 @@ namespace Catch { virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0; virtual std::string argsSynopsis() const = 0; virtual std::string optionSummary() const = 0; - virtual std::string optionDescription() const { return ""; }; + virtual std::string optionDescription() const { return ""; } std::string optionNames() const { std::string names; diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp index f8f2baa4..fc610748 100644 --- a/include/internal/catch_impl.hpp +++ b/include/internal/catch_impl.hpp @@ -28,6 +28,7 @@ #include "catch_tags.hpp" #include "catch_version.hpp" #include "catch_line_wrap.hpp" +#include "catch_message.hpp" #include "../reporters/catch_reporter_basic.hpp" #include "../reporters/catch_reporter_xml.hpp" diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h index 08147055..c6c327a6 100644 --- a/include/internal/catch_interfaces_capture.h +++ b/include/internal/catch_interfaces_capture.h @@ -16,24 +16,27 @@ namespace Catch { class TestCase; - class ScopedInfo; class ExpressionResultBuilder; class AssertionResult; struct AssertionInfo; struct SectionInfo; + class MessageBuilder; + class ScopedMessageBuilder; struct IResultCapture { virtual ~IResultCapture(); - virtual void testEnded( AssertionResult const& result ) = 0; + virtual void assertionEnded( AssertionResult const& result ) = 0; virtual bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) = 0; virtual void sectionEnded( SectionInfo const& name, Counts const& assertions ) = 0; - virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0; - virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0; + virtual void pushScopedMessage( ScopedMessageBuilder const& _builder ) = 0; + virtual void popScopedMessage( ScopedMessageBuilder const& _builder ) = 0; + virtual bool shouldDebugBreak() const = 0; + virtual void acceptMessage( const MessageBuilder& messageBuilder ) = 0; virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) = 0; virtual std::string getCurrentTestName() const = 0; diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index e6743f06..8fa7cf1a 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -14,6 +14,7 @@ #include "catch_config.hpp" #include "catch_test_case_info.h" #include "catch_assertionresult.h" +#include "catch_message.h" #include "catch_option.hpp" #include @@ -89,13 +90,24 @@ namespace Catch struct AssertionStats { AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, Totals const& _totals ) : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), totals( _totals ) - {} + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + infoMessages.push_back( builder.build() ); + } + } virtual ~AssertionStats(); AssertionResult assertionResult; + std::vector infoMessages; Totals totals; }; diff --git a/include/internal/catch_message.h b/include/internal/catch_message.h new file mode 100644 index 00000000..b3d4af1e --- /dev/null +++ b/include/internal/catch_message.h @@ -0,0 +1,66 @@ +/* + * Created by Phil Nash on 1/2/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include +#include "catch_result_type.h" +#include "catch_common.h" + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + + class MessageBuilder : public MessageInfo { + public: + MessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + MessageInfo build() const; + + template + MessageBuilder& operator << ( T const& _value ) { + stream << _value; + return *this; + } + private: + std::ostringstream stream; + }; + + class ScopedMessageBuilder : public MessageBuilder { + public: + ScopedMessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + ~ScopedMessageBuilder(); + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED diff --git a/include/internal/catch_message.hpp b/include/internal/catch_message.hpp new file mode 100644 index 00000000..c6996aa9 --- /dev/null +++ b/include/internal/catch_message.hpp @@ -0,0 +1,57 @@ +/* + * Created by Phil Nash on 1/2/2013. + * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +#include "catch_message.h" + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + MessageBuilder::MessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : MessageInfo( _macroName, _lineInfo, _type ) + {} + + MessageInfo MessageBuilder::build() const { + MessageInfo message = *this; + message.message = stream.str(); + return message; + } + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessageBuilder::ScopedMessageBuilder + ( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : MessageBuilder( _macroName, _lineInfo, _type ) + {} + + ScopedMessageBuilder::~ScopedMessageBuilder() { + getResultCapture().popScopedMessage( *this ); + } + + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED diff --git a/include/internal/catch_result_type.h b/include/internal/catch_result_type.h index 5492531e..36aab4c9 100644 --- a/include/internal/catch_result_type.h +++ b/include/internal/catch_result_type.h @@ -32,6 +32,9 @@ namespace Catch { inline bool isOk( ResultWas::OfType resultType ) { return ( resultType & ResultWas::FailureBit ) == 0; } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } // ResultAction::Value enum struct ResultAction { enum Value { diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp index 03f1fcde..b51a3828 100644 --- a/include/internal/catch_runner_impl.hpp +++ b/include/internal/catch_runner_impl.hpp @@ -155,43 +155,28 @@ namespace Catch { private: // IResultCapture + virtual void acceptMessage( const MessageBuilder& messageBuilder ) { + m_messages.push_back( messageBuilder.build() ); + } + virtual ResultAction::Value acceptExpression( const ExpressionResultBuilder& assertionResult, const AssertionInfo& assertionInfo ) { m_lastAssertionInfo = assertionInfo; return actOnCurrentResult( assertionResult.buildResult( assertionInfo ) ); } - virtual void testEnded( const AssertionResult& result ) { + virtual void assertionEnded( const AssertionResult& result ) { if( result.getResultType() == ResultWas::Ok ) { m_totals.assertions.passed++; } else if( !result.isOk() ) { m_totals.assertions.failed++; - - { - std::vector::const_iterator it = m_scopedInfos.begin(); - std::vector::const_iterator itEnd = m_scopedInfos.end(); - for(; it != itEnd; ++it ) - m_reporter->assertionEnded( AssertionStats( (*it)->buildResult( m_lastAssertionInfo ), m_totals ) ); - } - { - std::vector::const_iterator it = m_assertionResults.begin(); - std::vector::const_iterator itEnd = m_assertionResults.end(); - for(; it != itEnd; ++it ) - m_reporter->assertionEnded( AssertionStats( *it, m_totals ) ); - } - m_assertionResults.clear(); } - if( result.getResultType() == ResultWas::Info ) - { - m_assertionResults.push_back( result ); - m_totals.assertions.info++; - } - else - m_reporter->assertionEnded( AssertionStats( result, m_totals ) ); + m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ); - // Reset AssertionInfo - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after this line}" , m_lastAssertionInfo.resultDisposition ); + // Reset working state + m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_messages.clear(); } virtual bool sectionStarted ( @@ -229,18 +214,18 @@ namespace Catch { m_runningTest->endSection( info.name ); m_reporter->sectionEnded( SectionStats( info, assertions, missingAssertions ) ); + m_messages.clear(); } - virtual void pushScopedInfo( ScopedInfo* scopedInfo ) { - m_scopedInfos.push_back( scopedInfo ); + virtual void pushScopedMessage( ScopedMessageBuilder const& _builder ) { + m_messages.push_back( _builder.build() ); + } + + virtual void popScopedMessage( ScopedMessageBuilder const& _builder ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), _builder ), m_messages.end() ); } - virtual void popScopedInfo( ScopedInfo* scopedInfo ) { - if( m_scopedInfos.back() == scopedInfo ) - m_scopedInfos.pop_back(); - } - - virtual bool shouldDebugBreak() const { + virtual bool shouldDebugBreak() const { return m_config.shouldDebugBreak(); } @@ -264,7 +249,7 @@ namespace Catch { ResultAction::Value actOnCurrentResult( const AssertionResult& result ) { m_lastResult = result; - testEnded( m_lastResult ); + assertionEnded( m_lastResult ); ResultAction::Value action = ResultAction::None; @@ -282,6 +267,7 @@ namespace Catch { try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal ); m_runningTest->reset(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( std::cout, redirectedCout ); StreamRedirect cerrRedir( std::cerr, redirectedCerr ); @@ -300,7 +286,7 @@ namespace Catch { exResult << translateActiveException(); actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) ); } - m_assertionResults.clear(); + m_messages.clear(); } private: @@ -312,8 +298,7 @@ namespace Catch { const Config& m_config; Totals m_totals; Ptr m_reporter; - std::vector m_scopedInfos; - std::vector m_assertionResults; + std::vector m_messages; IRunner* m_prevRunner; IResultCapture* m_prevResultCapture; const IConfig* m_prevConfig; diff --git a/include/internal/catch_totals.hpp b/include/internal/catch_totals.hpp index 9f854580..03832a2e 100644 --- a/include/internal/catch_totals.hpp +++ b/include/internal/catch_totals.hpp @@ -13,19 +13,17 @@ namespace Catch { struct Counts { - Counts() : passed( 0 ), failed( 0 ), info( 0 ) {} + Counts() : passed( 0 ), failed( 0 ) {} Counts operator - ( const Counts& other ) const { Counts diff; diff.passed = passed - other.passed; diff.failed = failed - other.failed; - diff.info = info - other.info; return diff; } Counts& operator += ( const Counts& other ) { passed += other.passed; failed += other.failed; - info += other.info; return *this; } @@ -35,7 +33,6 @@ namespace Catch { std::size_t passed; std::size_t failed; - std::size_t info; }; struct Totals { diff --git a/include/reporters/catch_reporter_console.hpp b/include/reporters/catch_reporter_console.hpp index 3101dab9..3acfb8e9 100644 --- a/include/reporters/catch_reporter_console.hpp +++ b/include/reporters/catch_reporter_console.hpp @@ -98,14 +98,18 @@ namespace Catch { stats( _stats ), result( _stats.assertionResult ), colour( TextColour::None ), - message( result.getMessage() ) + message( result.getMessage() ), + messages( _stats.infoMessages ) { switch( result.getResultType() ) { case ResultWas::Ok: colour = TextColour::Success; passOrFail = "PASSED"; - if( result.hasMessage() ) + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; break; case ResultWas::ExpressionFailed: if( result.isOk() ) { @@ -116,9 +120,13 @@ namespace Catch { colour = TextColour::Error; passOrFail = "FAILED"; } - if( result.hasMessage() ){ + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; - } + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; +// if( result.hasMessage() ){ +// messageLabel = "with message"; +// } break; case ResultWas::ThrewException: colour = TextColour::Error; @@ -139,13 +147,21 @@ namespace Catch { case ResultWas::ExplicitFailure: passOrFail = "FAILED"; colour = TextColour::Error; - messageLabel = "explicitly with message"; +// messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; break; case ResultWas::Exception: passOrFail = "FAILED"; colour = TextColour::Error; - if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; +// if( result.hasMessage() ) +// messageLabel = "with message"; break; // These cases are here to prevent compiler warnings @@ -196,8 +212,13 @@ namespace Catch { void printMessage() const { if( !messageLabel.empty() ) stream << messageLabel << ":" << "\n"; - if( !message.empty() ) - stream << wrapLongStrings( message ) << "\n"; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + stream << wrapLongStrings( it->message ) << "\n"; + } +// if( !message.empty() ) +// stream << wrapLongStrings( message ) << "\n"; } void printSourceInfo() const { TextColour colourGuard( TextColour::FileName ); @@ -215,6 +236,7 @@ namespace Catch { std::string passOrFail; std::string messageLabel; std::string message; + std::vector messages; }; void lazyPrint() { diff --git a/projects/SelfTest/Baselines/approvedResults.txt b/projects/SelfTest/Baselines/approvedResults.txt index 78475fcb..eaaa6139 100644 --- a/projects/SelfTest/Baselines/approvedResults.txt +++ b/projects/SelfTest/Baselines/approvedResults.txt @@ -1,5 +1,5 @@ -CatchSelfTest is a CATCH v0.9 b15 (integration) host application. +CatchSelfTest is a CATCH v0.9 b17 (integration) host application. Run with -? for options ------------------------------------------------------------------------------- @@ -1055,7 +1055,7 @@ PASSED: ExceptionTests.cpp:60: FAILED: - {Unknown expression after this line} + {Unknown expression after the reported line} due to unexpected exception with message: unexpected exception ExceptionTests.cpp:60: @@ -2002,6 +2002,7 @@ GeneratorTests.cpp:40: ............................................................................... warning: + this is a message this is a warning MessageTests.cpp:14: @@ -2021,18 +2022,13 @@ MessageTests.cpp:18: ./failing/message/info/1 ............................................................................... -info: - this message should be logged -MessageTests.cpp:23: - -info: - so should this -MessageTests.cpp:24: - FAILED: REQUIRE( a == 1 ) with expansion: 2 == 1 +with messages: + this message should be logged + so should this MessageTests.cpp:26: ------------------------------------------------------------------------------- @@ -2043,36 +2039,32 @@ PASSED: CHECK( a == 2 ) with expansion: 2 == 2 +with message: + this message should not be logged MessageTests.cpp:33: -info: - this message should be logged -MessageTests.cpp:31: - -info: - this message should be logged, too -MessageTests.cpp:35: - FAILED: CHECK( a == 1 ) with expansion: 2 == 1 +with message: + this message should be logged MessageTests.cpp:37: -info: - and this, but later -MessageTests.cpp:39: - FAILED: CHECK( a == 0 ) with expansion: 2 == 0 +with message: + and this, but later MessageTests.cpp:41: PASSED: CHECK( a == 2 ) with expansion: 2 == 2 +with message: + but not this MessageTests.cpp:45: ------------------------------------------------------------------------------- @@ -2130,76 +2122,99 @@ PASSED: REQUIRE( i < 10 ) with expansion: 0 < 10 +with messages: + current counter 0 + i := 0 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 1 < 10 +with messages: + current counter 1 + i := 1 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 2 < 10 +with messages: + current counter 2 + i := 2 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 3 < 10 +with messages: + current counter 3 + i := 3 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 4 < 10 +with messages: + current counter 4 + i := 4 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 5 < 10 +with messages: + current counter 5 + i := 5 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 6 < 10 +with messages: + current counter 6 + i := 6 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 7 < 10 +with messages: + current counter 7 + i := 7 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 8 < 10 +with messages: + current counter 8 + i := 8 MessageTests.cpp:86: PASSED: REQUIRE( i < 10 ) with expansion: 9 < 10 -MessageTests.cpp:86: - - REQUIRE( i < 10 ) -info: - current counter 10 -MessageTests.cpp:86: - - REQUIRE( i < 10 ) -info: - i := 10 +with messages: + current counter 9 + i := 9 MessageTests.cpp:86: FAILED: REQUIRE( i < 10 ) with expansion: 10 < 10 +with messages: + current counter 10 + i := 10 MessageTests.cpp:86: ------------------------------------------------------------------------------- @@ -2213,6 +2228,22 @@ MessageTests.cpp:92: No assertions in test case, './succeeding/nofail' +------------------------------------------------------------------------------- +just info +............................................................................... + + +No assertions in test case, 'just info' + +------------------------------------------------------------------------------- +just failure +............................................................................... + +FAILED: +explicitly with message: + Previous info should not be seen +MessageTests.cpp:101: + ------------------------------------------------------------------------------- ./succeeding/Misc/Sections s1 @@ -2347,84 +2378,68 @@ MiscTests.cpp:103: ./mixed/Misc/loops ............................................................................... -info: +FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: Testing if fib[0] (1) is even -MiscTests.cpp:114: +MiscTests.cpp:115: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 -MiscTests.cpp:115: - -info: +with message: Testing if fib[1] (1) is even -MiscTests.cpp:114: - -FAILED: - CHECK( ( fib[i] % 2 ) == 0 ) -with expansion: - 1 == 0 MiscTests.cpp:115: PASSED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 0 == 0 -MiscTests.cpp:115: - -info: +with message: Testing if fib[2] (2) is even -MiscTests.cpp:114: - -info: - Testing if fib[3] (3) is even -MiscTests.cpp:114: - -FAILED: - CHECK( ( fib[i] % 2 ) == 0 ) -with expansion: - 1 == 0 MiscTests.cpp:115: -info: - Testing if fib[4] (5) is even -MiscTests.cpp:114: +FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[3] (3) is even +MiscTests.cpp:115: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 +with message: + Testing if fib[4] (5) is even MiscTests.cpp:115: PASSED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 0 == 0 -MiscTests.cpp:115: - -info: +with message: Testing if fib[5] (8) is even -MiscTests.cpp:114: - -info: - Testing if fib[6] (13) is even -MiscTests.cpp:114: - -FAILED: - CHECK( ( fib[i] % 2 ) == 0 ) -with expansion: - 1 == 0 MiscTests.cpp:115: -info: - Testing if fib[7] (21) is even -MiscTests.cpp:114: +FAILED: + CHECK( ( fib[i] % 2 ) == 0 ) +with expansion: + 1 == 0 +with message: + Testing if fib[6] (13) is even +MiscTests.cpp:115: FAILED: CHECK( ( fib[i] % 2 ) == 0 ) with expansion: 1 == 0 +with message: + Testing if fib[7] (21) is even MiscTests.cpp:115: Some information @@ -2456,16 +2471,11 @@ MiscTests.cpp:134: ./failing/info ............................................................................... -info: - hi -MiscTests.cpp:139: - -info: - i := 7 -MiscTests.cpp:141: - FAILED: REQUIRE( false ) +with messages: + hi + i := 7 MiscTests.cpp:142: ------------------------------------------------------------------------------- @@ -2552,12 +2562,10 @@ No assertions in section, 'encoded chars' ./manual/onechar ............................................................................... -info: - 3 -MiscTests.cpp:195: - FAILED: REQUIRE( false ) +with message: + 3 MiscTests.cpp:196: ------------------------------------------------------------------------------- @@ -4243,10 +4251,10 @@ with expansion: BDDTests.cpp:29: =============================================================================== -96 test cases - 45 failed (610 assertions - 102 failed) +98 test cases - 47 failed (612 assertions - 104 failed) -CatchSelfTest is a CATCH v0.9 b15 (integration) host application. +CatchSelfTest is a CATCH v0.9 b17 (integration) host application. Run with -? for options ------------------------------------------------------------------------------- @@ -4525,7 +4533,7 @@ ConditionTests.cpp:72: 12 test cases - 3 failed (38 assertions - 4 failed) - + @@ -4715,7 +4723,7 @@ ExceptionTests.cpp:52 - + ExceptionTests.cpp:60 @@ -4750,29 +4758,14 @@ MessageTests.cpp:14 - -MessageTests.cpp:23 - - -MessageTests.cpp:24 - MessageTests.cpp:26 - -MessageTests.cpp:31 - - -MessageTests.cpp:35 - MessageTests.cpp:37 - -MessageTests.cpp:39 - MessageTests.cpp:41 @@ -4797,12 +4790,6 @@ Message from section two - -MessageTests.cpp:86 - - -MessageTests.cpp:86 - MessageTests.cpp:86 @@ -4812,6 +4799,12 @@ MessageTests.cpp:86 MessageTests.cpp:92 + + + +MessageTests.cpp:101 + + @@ -4826,45 +4819,21 @@ MiscTests.cpp:103 - -MiscTests.cpp:114 - MiscTests.cpp:115 - -MiscTests.cpp:114 - MiscTests.cpp:115 - -MiscTests.cpp:114 - - -MiscTests.cpp:114 - MiscTests.cpp:115 - -MiscTests.cpp:114 - MiscTests.cpp:115 - -MiscTests.cpp:114 - - -MiscTests.cpp:114 - MiscTests.cpp:115 - -MiscTests.cpp:114 - MiscTests.cpp:115 @@ -4879,12 +4848,6 @@ An error - -MiscTests.cpp:139 - - -MiscTests.cpp:141 - MiscTests.cpp:142 @@ -4909,9 +4872,6 @@ MiscTests.cpp:178 - -MiscTests.cpp:195 - MiscTests.cpp:196 @@ -6403,10 +6363,10 @@ ExceptionTests.cpp" line="60"> ExceptionTests.cpp" line="60"> - {Unknown expression after this line} + {Unknown expression after the reported line} - {Unknown expression after this line} + {Unknown expression after the reported line} ExceptionTests.cpp" line="60"> unexpected exception @@ -7652,12 +7612,6 @@ GeneratorTests.cpp" line="40"> - - this message should be logged - - - so should this - MessageTests.cpp" line="26"> a == 1 @@ -7677,12 +7631,6 @@ MessageTests.cpp" line="33"> 2 == 2 - - this message should be logged - - - this message should be logged, too - MessageTests.cpp" line="37"> a == 1 @@ -7691,9 +7639,6 @@ MessageTests.cpp" line="37"> 2 == 1 - - and this, but later - MessageTests.cpp" line="41"> a == 0 @@ -7823,28 +7768,6 @@ MessageTests.cpp" line="86"> 9 < 10 -MessageTests.cpp" line="86"> - - i < 10 - - - i < 10 - - - current counter 10 - - -MessageTests.cpp" line="86"> - - i < 10 - - - i < 10 - - - i := 10 - - MessageTests.cpp" line="86"> i < 10 @@ -7866,6 +7789,15 @@ MessageTests.cpp" line="92"> + + + + + + Previous info should not be seen + + +
MiscTests.cpp" line="25"> @@ -8013,9 +7945,6 @@ MiscTests.cpp" line="103"> - - Testing if fib[0] (1) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8024,9 +7953,6 @@ MiscTests.cpp" line="115"> 1 == 0 - - Testing if fib[1] (1) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8043,12 +7969,6 @@ MiscTests.cpp" line="115"> 0 == 0 - - Testing if fib[2] (2) is even - - - Testing if fib[3] (3) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8057,9 +7977,6 @@ MiscTests.cpp" line="115"> 1 == 0 - - Testing if fib[4] (5) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8076,12 +7993,6 @@ MiscTests.cpp" line="115"> 0 == 0 - - Testing if fib[5] (8) is even - - - Testing if fib[6] (13) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8090,9 +8001,6 @@ MiscTests.cpp" line="115"> 1 == 0 - - Testing if fib[7] (21) is even - MiscTests.cpp" line="115"> ( fib[i] % 2 ) == 0 @@ -8126,12 +8034,6 @@ MiscTests.cpp" line="134"> - - hi - - - i := 7 - MiscTests.cpp" line="142"> false @@ -8228,9 +8130,6 @@ MiscTests.cpp" line="178"> - - 3 - MiscTests.cpp" line="196"> false @@ -9886,9 +9785,9 @@ BDDTests.cpp" line="29">
- + - + [Started testing: CatchSelfTest] [Started group: '~dummy'] @@ -10136,7 +10035,7 @@ ExceptionTests.cpp:52: Unexpected exception with message: 'unexpected exception' [Running: ./failing/exceptions/implicit/2] ExceptionTests.cpp:60: 1 == 1 succeeded -ExceptionTests.cpp:60: {Unknown expression after this line} failed with unexpected exception with message: 'unexpected exception' +ExceptionTests.cpp:60: {Unknown expression after the reported line} failed with unexpected exception with message: 'unexpected exception' [Finished: './failing/exceptions/implicit/2' 1 test case failed (1 of 2 assertions failed)] [Running: ./succeeding/exceptions/implicit] @@ -10330,17 +10229,12 @@ MessageTests.cpp:18: succeeded [Finished: './succeeding/succeed' All tests passed (1 assertion in 1 test case)] [Running: ./failing/message/info/1] -MessageTests.cpp:23: [info: this message should be logged] -MessageTests.cpp:24: [info: so should this] MessageTests.cpp:26: a == 1 failed for: 2 == 1 [Finished: './failing/message/info/1' 1 test case failed (1 assertion failed)] [Running: ./mixed/message/info/2] MessageTests.cpp:33: a == 2 succeeded for: 2 == 2 -MessageTests.cpp:31: [info: this message should be logged] -MessageTests.cpp:35: [info: this message should be logged, too] MessageTests.cpp:37: a == 1 failed for: 2 == 1 -MessageTests.cpp:39: [info: and this, but later] MessageTests.cpp:41: a == 0 failed for: 2 == 0 MessageTests.cpp:45: a == 2 succeeded for: 2 == 2 [Finished: './mixed/message/info/2' 1 test case failed (2 of 4 assertions failed)] @@ -10389,8 +10283,6 @@ MessageTests.cpp:86: i < 10 succeeded for: 6 < 10 MessageTests.cpp:86: i < 10 succeeded for: 7 < 10 MessageTests.cpp:86: i < 10 succeeded for: 8 < 10 MessageTests.cpp:86: i < 10 succeeded for: 9 < 10 -MessageTests.cpp:86: i < 10 succeeded[info: current counter 10] -MessageTests.cpp:86: i < 10 succeeded[info: i := 10] MessageTests.cpp:86: i < 10 failed for: 10 < 10 [Finished: './mixed/message/scoped' 1 test case failed (1 of 11 assertions failed)] @@ -10401,6 +10293,16 @@ No assertions in test case, './succeeding/nofail' [Finished: './succeeding/nofail' 1 test case failed (1 assertion failed)] +[Running: just info] + +No assertions in test case, 'just info' + +[Finished: 'just info' 1 test case failed (1 assertion failed)] + +[Running: just failure] +MessageTests.cpp:101: failed with message: 'Previous info should not be seen' +[Finished: 'just failure' 1 test case failed (1 assertion failed)] + [Running: ./succeeding/Misc/Sections] [Started section: 's1'] MiscTests.cpp:25: a != b succeeded for: 1 != 2 @@ -10484,21 +10386,13 @@ MiscTests.cpp:103: b > a failed for: 0 > 1 [Finished: './mixed/Misc/Sections/loops' 1 test case failed (1 assertion failed)] [Running: ./mixed/Misc/loops] -MiscTests.cpp:114: [info: Testing if fib[0] (1) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 -MiscTests.cpp:114: [info: Testing if fib[1] (1) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 MiscTests.cpp:115: ( fib[i] % 2 ) == 0 succeeded for: 0 == 0 -MiscTests.cpp:114: [info: Testing if fib[2] (2) is even] -MiscTests.cpp:114: [info: Testing if fib[3] (3) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 -MiscTests.cpp:114: [info: Testing if fib[4] (5) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 MiscTests.cpp:115: ( fib[i] % 2 ) == 0 succeeded for: 0 == 0 -MiscTests.cpp:114: [info: Testing if fib[5] (8) is even] -MiscTests.cpp:114: [info: Testing if fib[6] (13) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 -MiscTests.cpp:114: [info: Testing if fib[7] (21) is even] MiscTests.cpp:115: ( fib[i] % 2 ) == 0 failed for: 1 == 0 [Finished: './mixed/Misc/loops' 1 test case failed (6 of 8 assertions failed)] Some information @@ -10516,8 +10410,6 @@ MiscTests.cpp:134: makeString( true ) == static_cast(__null) succeeded fo [Finished: './succeeding/Misc/null strings' All tests passed (2 assertions in 1 test case)] [Running: ./failing/info] -MiscTests.cpp:139: [info: hi] -MiscTests.cpp:141: [info: i := 7] MiscTests.cpp:142: false failed [Finished: './failing/info' 1 test case failed (1 assertion failed)] @@ -10557,7 +10449,6 @@ No assertions in section, 'encoded chars' [Finished: './misc/xmlentitycheck' 1 test case failed (All 2 assertions failed)] [Running: ./manual/onechar] -MiscTests.cpp:195: [info: 3] MiscTests.cpp:196: false failed [Finished: './manual/onechar' 1 test case failed (1 assertion failed)] @@ -11234,10 +11125,10 @@ BDDTests.cpp:29: itDoesThis() succeeded for: true [End of section: ' Given: This stuff exists' 1 assertion passed] [Finished: 'Scenario: Do that thing with the thing' All tests passed (1 assertion in 1 test case)] -[End of group: '~dummy'. 45 of 96 test cases failed (102 of 610 assertions failed)] +[End of group: '~dummy'. 47 of 98 test cases failed (104 of 612 assertions failed)] -[Testing completed. 45 of 96 test cases failed (102 of 610 assertions failed)] +[Testing completed. 47 of 98 test cases failed (104 of 612 assertions failed)] [Started testing: CatchSelfTest] [Started group: '~dummy'] diff --git a/projects/SelfTest/MessageTests.cpp b/projects/SelfTest/MessageTests.cpp index f7cfea35..0e010f6c 100644 --- a/projects/SelfTest/MessageTests.cpp +++ b/projects/SelfTest/MessageTests.cpp @@ -28,11 +28,11 @@ TEST_CASE( "./failing/message/info/1", "INFO gets logged on failure" ) TEST_CASE( "./mixed/message/info/2", "INFO gets logged on failure" ) { - INFO( "this message should be logged" ); + INFO( "this message should not be logged" ); int a = 2; CHECK( a == 2 ); - INFO( "this message should be logged, too" ); + INFO( "this message should be logged" ); CHECK( a == 1 ); @@ -91,3 +91,12 @@ TEST_CASE( "./succeeding/nofail", "The NO_FAIL macro reports a failure but does { CHECK_NOFAIL( 1 == 2 ); } + +TEST_CASE( "just info", "[info][isolated info]" ) +{ + INFO( "this should never be seen" ); +} +TEST_CASE( "just failure", "[fail][isolated info]" ) +{ + FAIL( "Previous info should not be seen" ); +} diff --git a/projects/SelfTest/SurrogateCpps/catch_message.cpp b/projects/SelfTest/SurrogateCpps/catch_message.cpp new file mode 100644 index 00000000..257c8b06 --- /dev/null +++ b/projects/SelfTest/SurrogateCpps/catch_message.cpp @@ -0,0 +1,2 @@ +// This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "catch_message.h" diff --git a/projects/SelfTest/catch_self_test.hpp b/projects/SelfTest/catch_self_test.hpp index cb62187f..44293e0c 100644 --- a/projects/SelfTest/catch_self_test.hpp +++ b/projects/SelfTest/catch_self_test.hpp @@ -115,7 +115,7 @@ namespace Catch { } break; } - }; + } private: Expected::Result m_expectedResult; diff --git a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index a8d139bb..f2777cb7 100644 --- a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; }; 2694A1FD16A0000E004816E3 /* catch_line_wrap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2694A1FB16A0000E004816E3 /* catch_line_wrap.cpp */; }; 4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */; }; 4A45DA2716161F1F004F8D6B /* catch_ptr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2616161F1F004F8D6B /* catch_ptr.cpp */; }; @@ -53,6 +54,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 26847E5B16BBAB790043B9C1 /* catch_message.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_message.h; sourceTree = ""; }; + 26847E5C16BBACB60043B9C1 /* catch_message.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_message.hpp; sourceTree = ""; }; + 26847E5D16BBADB40043B9C1 /* catch_message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_message.cpp; path = ../../../SelfTest/SurrogateCpps/catch_message.cpp; sourceTree = ""; }; 2694A1F8169FFF9B004816E3 /* catch_line_wrap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_line_wrap.h; sourceTree = ""; }; 2694A1FA169FFFEC004816E3 /* catch_line_wrap.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_line_wrap.hpp; sourceTree = ""; }; 2694A1FB16A0000E004816E3 /* catch_line_wrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catch_line_wrap.cpp; sourceTree = ""; }; @@ -275,6 +279,7 @@ 4AB3D9A1161621B500C9A0F8 /* catch_interfaces_generators.cpp */, 4ACE21CA166CA1B300FB5509 /* catch_option.cpp */, 2694A1FB16A0000E004816E3 /* catch_line_wrap.cpp */, + 26847E5D16BBADB40043B9C1 /* catch_message.cpp */, ); name = SurrogateCpps; sourceTree = ""; @@ -294,6 +299,7 @@ 4A90B59E15D2521E00EF71BC /* catch_expressionresult_builder.hpp */, 4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */, 2694A1FA169FFFEC004816E3 /* catch_line_wrap.hpp */, + 26847E5C16BBACB60043B9C1 /* catch_message.hpp */, ); name = impl; sourceTree = ""; @@ -314,6 +320,7 @@ 4AC91CCE155CF02800DC5117 /* catch_expression_lhs.hpp */, 4AC91CD0155D8DA600DC5117 /* catch_expression_decomposer.hpp */, 4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */, + 26847E5B16BBAB790043B9C1 /* catch_message.h */, ); name = Assertions; sourceTree = ""; @@ -473,6 +480,7 @@ 4AB3D9A2161621B500C9A0F8 /* catch_interfaces_generators.cpp in Sources */, 4ACE21CC166CA1B300FB5509 /* catch_option.cpp in Sources */, 2694A1FD16A0000E004816E3 /* catch_line_wrap.cpp in Sources */, + 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/single_include/catch.hpp b/single_include/catch.hpp index 602f6fad..e64fc8b8 100644 --- a/single_include/catch.hpp +++ b/single_include/catch.hpp @@ -1,6 +1,6 @@ /* - * CATCH v0.9 build 17 (integration branch) - * Generated: 2013-01-31 12:14:41.781000 + * CATCH v0.9 build 18 (integration branch) + * Generated: 2013-02-04 00:03:53.198397 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -656,6 +656,9 @@ namespace Catch { inline bool isOk( ResultWas::OfType resultType ) { return ( resultType & ResultWas::FailureBit ) == 0; } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } // ResultAction::Value enum struct ResultAction { enum Value { @@ -1036,6 +1039,61 @@ public: } // end namespace Catch +// #included from: catch_message.h +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + class MessageBuilder : public MessageInfo { + public: + MessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + MessageInfo build() const; + + template + MessageBuilder& operator << ( T const& _value ) { + stream << _value; + return *this; + } + private: + std::ostringstream stream; + }; + + class ScopedMessageBuilder : public MessageBuilder { + public: + ScopedMessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + ~ScopedMessageBuilder(); + }; + +} // end namespace Catch + // #included from: catch_interfaces_capture.h #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED @@ -1048,19 +1106,17 @@ public: namespace Catch { struct Counts { - Counts() : passed( 0 ), failed( 0 ), info( 0 ) {} + Counts() : passed( 0 ), failed( 0 ) {} Counts operator - ( const Counts& other ) const { Counts diff; diff.passed = passed - other.passed; diff.failed = failed - other.failed; - diff.info = info - other.info; return diff; } Counts& operator += ( const Counts& other ) { passed += other.passed; failed += other.failed; - info += other.info; return *this; } @@ -1070,7 +1126,6 @@ namespace Catch { std::size_t passed; std::size_t failed; - std::size_t info; }; struct Totals { @@ -1106,24 +1161,27 @@ namespace Catch { namespace Catch { class TestCase; - class ScopedInfo; class ExpressionResultBuilder; class AssertionResult; struct AssertionInfo; struct SectionInfo; + class MessageBuilder; + class ScopedMessageBuilder; struct IResultCapture { virtual ~IResultCapture(); - virtual void testEnded( AssertionResult const& result ) = 0; + virtual void assertionEnded( AssertionResult const& result ) = 0; virtual bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) = 0; virtual void sectionEnded( SectionInfo const& name, Counts const& assertions ) = 0; - virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0; - virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0; + virtual void pushScopedMessage( ScopedMessageBuilder const& _builder ) = 0; + virtual void popScopedMessage( ScopedMessageBuilder const& _builder ) = 0; + virtual bool shouldDebugBreak() const = 0; + virtual void acceptMessage( const MessageBuilder& messageBuilder ) = 0; virtual ResultAction::Value acceptExpression( ExpressionResultBuilder const& assertionResult, AssertionInfo const& assertionInfo ) = 0; virtual std::string getCurrentTestName() const = 0; @@ -2034,13 +2092,24 @@ namespace Catch struct AssertionStats { AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, Totals const& _totals ) : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), totals( _totals ) - {} + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + infoMessages.push_back( builder.build() ); + } + } virtual ~AssertionStats(); AssertionResult assertionResult; + std::vector infoMessages; Totals totals; }; @@ -2458,27 +2527,6 @@ namespace Catch { struct TestFailureException{}; -class ScopedInfo { -public: - ScopedInfo() : m_resultBuilder( ResultWas::Info ) { - getResultCapture().pushScopedInfo( this ); - } - ~ScopedInfo() { - getResultCapture().popScopedInfo( this ); - } - template - ScopedInfo& operator << ( const T& value ) { - m_resultBuilder << value; - return *this; - } - AssertionResult buildResult( const AssertionInfo& assertionInfo ) const { - return m_resultBuilder.buildResult( assertionInfo ); - } - -private: - ExpressionResultBuilder m_resultBuilder; -}; - // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool isTrue( bool value ){ return value; } @@ -2572,17 +2620,23 @@ inline bool isTrue( bool value ){ return value; } } while( Catch::isTrue( false ) ) /////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_MSG( reason, resultType, resultDisposition, macroName ) \ +#define INTERNAL_CATCH_INFO( log, macroName ) \ + do { \ + Catch::getResultCapture().acceptMessage( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); \ + } while( Catch::isTrue( false ) ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG( log, messageType, resultDisposition, macroName ) \ do { \ INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \ - INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( resultType ) << reason, resultDisposition, true ) \ + INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( messageType ) << log, resultDisposition, true ) \ } while( Catch::isTrue( false ) ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_SCOPED_INFO( log, macroName ) \ - INTERNAL_CATCH_ACCEPT_INFO( "", macroName, Catch::ResultDisposition::Normal ); \ - Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \ - INTERNAL_CATCH_UNIQUE_NAME( info ) << log + Catch::ScopedMessageBuilder INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ); \ + INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) << log; \ + Catch::getResultCapture().pushScopedMessage( INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ @@ -3522,7 +3576,7 @@ namespace Catch { virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0; virtual std::string argsSynopsis() const = 0; virtual std::string optionSummary() const = 0; - virtual std::string optionDescription() const { return ""; }; + virtual std::string optionDescription() const { return ""; } std::string optionNames() const { std::string names; @@ -4446,43 +4500,28 @@ namespace Catch { private: // IResultCapture + virtual void acceptMessage( const MessageBuilder& messageBuilder ) { + m_messages.push_back( messageBuilder.build() ); + } + virtual ResultAction::Value acceptExpression( const ExpressionResultBuilder& assertionResult, const AssertionInfo& assertionInfo ) { m_lastAssertionInfo = assertionInfo; return actOnCurrentResult( assertionResult.buildResult( assertionInfo ) ); } - virtual void testEnded( const AssertionResult& result ) { + virtual void assertionEnded( const AssertionResult& result ) { if( result.getResultType() == ResultWas::Ok ) { m_totals.assertions.passed++; } else if( !result.isOk() ) { m_totals.assertions.failed++; - - { - std::vector::const_iterator it = m_scopedInfos.begin(); - std::vector::const_iterator itEnd = m_scopedInfos.end(); - for(; it != itEnd; ++it ) - m_reporter->assertionEnded( AssertionStats( (*it)->buildResult( m_lastAssertionInfo ), m_totals ) ); - } - { - std::vector::const_iterator it = m_assertionResults.begin(); - std::vector::const_iterator itEnd = m_assertionResults.end(); - for(; it != itEnd; ++it ) - m_reporter->assertionEnded( AssertionStats( *it, m_totals ) ); - } - m_assertionResults.clear(); } - if( result.getResultType() == ResultWas::Info ) - { - m_assertionResults.push_back( result ); - m_totals.assertions.info++; - } - else - m_reporter->assertionEnded( AssertionStats( result, m_totals ) ); + m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ); - // Reset AssertionInfo - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after this line}" , m_lastAssertionInfo.resultDisposition ); + // Reset working state + m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_messages.clear(); } virtual bool sectionStarted ( @@ -4519,15 +4558,15 @@ namespace Catch { m_runningTest->endSection( info.name ); m_reporter->sectionEnded( SectionStats( info, assertions, missingAssertions ) ); + m_messages.clear(); } - virtual void pushScopedInfo( ScopedInfo* scopedInfo ) { - m_scopedInfos.push_back( scopedInfo ); + virtual void pushScopedMessage( ScopedMessageBuilder const& _builder ) { + m_messages.push_back( _builder.build() ); } - virtual void popScopedInfo( ScopedInfo* scopedInfo ) { - if( m_scopedInfos.back() == scopedInfo ) - m_scopedInfos.pop_back(); + virtual void popScopedMessage( ScopedMessageBuilder const& _builder ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), _builder ), m_messages.end() ); } virtual bool shouldDebugBreak() const { @@ -4554,7 +4593,7 @@ namespace Catch { ResultAction::Value actOnCurrentResult( const AssertionResult& result ) { m_lastResult = result; - testEnded( m_lastResult ); + assertionEnded( m_lastResult ); ResultAction::Value action = ResultAction::None; @@ -4572,6 +4611,7 @@ namespace Catch { try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal ); m_runningTest->reset(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( std::cout, redirectedCout ); StreamRedirect cerrRedir( std::cerr, redirectedCerr ); @@ -4590,7 +4630,7 @@ namespace Catch { exResult << translateActiveException(); actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo ) ); } - m_assertionResults.clear(); + m_messages.clear(); } private: @@ -4602,8 +4642,7 @@ namespace Catch { const Config& m_config; Totals m_totals; Ptr m_reporter; - std::vector m_scopedInfos; - std::vector m_assertionResults; + std::vector m_messages; IRunner* m_prevRunner; IResultCapture* m_prevResultCapture; const IConfig* m_prevConfig; @@ -5794,7 +5833,7 @@ namespace Catch { namespace Catch { // These numbers are maintained by a script - Version libraryVersion( 0, 9, 17, "integration" ); + Version libraryVersion( 0, 9, 18, "integration" ); } // #included from: catch_line_wrap.hpp @@ -5854,6 +5893,52 @@ namespace Catch { } // end namespace Catch +// #included from: catch_message.hpp +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + MessageBuilder::MessageBuilder( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : MessageInfo( _macroName, _lineInfo, _type ) + {} + + MessageInfo MessageBuilder::build() const { + MessageInfo message = *this; + message.message = stream.str(); + return message; + } + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessageBuilder::ScopedMessageBuilder + ( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : MessageBuilder( _macroName, _lineInfo, _type ) + {} + + ScopedMessageBuilder::~ScopedMessageBuilder() { + getResultCapture().popScopedMessage( *this ); + } + +} // end namespace Catch + // #included from: ../reporters/catch_reporter_basic.hpp #define TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED @@ -6917,14 +7002,18 @@ namespace Catch { stats( _stats ), result( _stats.assertionResult ), colour( TextColour::None ), - message( result.getMessage() ) + message( result.getMessage() ), + messages( _stats.infoMessages ) { switch( result.getResultType() ) { case ResultWas::Ok: colour = TextColour::Success; passOrFail = "PASSED"; - if( result.hasMessage() ) + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; break; case ResultWas::ExpressionFailed: if( result.isOk() ) { @@ -6935,9 +7024,13 @@ namespace Catch { colour = TextColour::Error; passOrFail = "FAILED"; } - if( result.hasMessage() ){ + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; - } + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; +// if( result.hasMessage() ){ +// messageLabel = "with message"; +// } break; case ResultWas::ThrewException: colour = TextColour::Error; @@ -6958,13 +7051,21 @@ namespace Catch { case ResultWas::ExplicitFailure: passOrFail = "FAILED"; colour = TextColour::Error; - messageLabel = "explicitly with message"; +// messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; break; case ResultWas::Exception: passOrFail = "FAILED"; colour = TextColour::Error; - if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; +// if( result.hasMessage() ) +// messageLabel = "with message"; break; // These cases are here to prevent compiler warnings @@ -7015,8 +7116,13 @@ namespace Catch { void printMessage() const { if( !messageLabel.empty() ) stream << messageLabel << ":" << "\n"; - if( !message.empty() ) - stream << wrapLongStrings( message ) << "\n"; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + stream << wrapLongStrings( it->message ) << "\n"; + } +// if( !message.empty() ) +// stream << wrapLongStrings( message ) << "\n"; } void printSourceInfo() const { TextColour colourGuard( TextColour::FileName ); @@ -7034,6 +7140,7 @@ namespace Catch { std::string passOrFail; std::string messageLabel; std::string message; + std::vector messages; }; void lazyPrint() { @@ -7296,12 +7403,12 @@ int main (int argc, char * const argv[]) { #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) -#define CATCH_INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CATCH_INFO" ) +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN" ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL" ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED" ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "CATCH_SCOPED_INFO" ) -#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CAPTURE" ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "CATCH_SCOPED_CAPTURE" ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) @@ -7339,12 +7446,12 @@ int main (int argc, char * const argv[]) { #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) -#define INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "INFO" ) +#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) #define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN" ) #define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL" ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED" ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "SCOPED_INFO" ) -#define CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, Catch::ResultDisposition::ContinueOnFailure, "CAPTURE" ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "SCOPED_CAPTURE" ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )