diff options
author | 2017-08-11 22:09:00 +0300 | |
---|---|---|
committer | 2017-08-11 22:09:00 +0300 | |
commit | fda201203b988ed1543bea5d03ba0a62fb11f6e0 (patch) | |
tree | 3240159539cd48657e2440b0b5a9aa0b6c4162c7 /test/catch.hpp | |
parent | cc5d03efe84da2d806087a2138fb9c583cefb113 (diff) | |
download | newsboat-fda201203b988ed1543bea5d03ba0a62fb11f6e0.tar.gz newsboat-fda201203b988ed1543bea5d03ba0a62fb11f6e0.tar.zst newsboat-fda201203b988ed1543bea5d03ba0a62fb11f6e0.zip |
Update Catch to 1.9.7
Diffstat (limited to '')
-rw-r--r-- | test/catch.hpp | 348 |
1 files changed, 229 insertions, 119 deletions
diff --git a/test/catch.hpp b/test/catch.hpp index 33d037e5..7c351e93 100644 --- a/test/catch.hpp +++ b/test/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v1.9.4 - * Generated: 2017-05-16 13:51:55.506519 + * Catch v1.9.7 + * Generated: 2017-08-10 23:49:15.233907 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -145,6 +145,11 @@ #endif +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + //////////////////////////////////////////////////////////////////////////////// // Cygwin #ifdef __CYGWIN__ @@ -220,7 +225,7 @@ // Use __COUNTER__ if the compiler supports it #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ - ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ + ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ ( defined __clang__ && __clang_major__ >= 3 ) #define CATCH_INTERNAL_CONFIG_COUNTER @@ -414,14 +419,14 @@ namespace Catch { }; template<typename ContainerT> - inline void deleteAll( ContainerT& container ) { + void deleteAll( ContainerT& container ) { typename ContainerT::const_iterator it = container.begin(); typename ContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete *it; } template<typename AssociativeContainerT> - inline void deleteAllValues( AssociativeContainerT& container ) { + void deleteAllValues( AssociativeContainerT& container ) { typename AssociativeContainerT::const_iterator it = container.begin(); typename AssociativeContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) @@ -501,7 +506,6 @@ namespace Catch { { public: NotImplementedException( SourceLineInfo const& lineInfo ); - NotImplementedException( NotImplementedException const& ) {} virtual ~NotImplementedException() CATCH_NOEXCEPT {} @@ -771,7 +775,7 @@ void registerTestCaseFunction #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ @@ -780,7 +784,7 @@ void registerTestCaseFunction /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// @@ -790,7 +794,7 @@ void registerTestCaseFunction struct TestName : ClassName{ \ void test(); \ }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestName::test() @@ -800,7 +804,7 @@ void registerTestCaseFunction /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #else @@ -808,7 +812,7 @@ void registerTestCaseFunction #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ static void TestName(); \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ static void TestName() #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ @@ -817,7 +821,7 @@ void registerTestCaseFunction /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS /////////////////////////////////////////////////////////////////////////////// @@ -827,7 +831,7 @@ void registerTestCaseFunction struct TestCaseName : ClassName{ \ void test(); \ }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ } \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ void TestCaseName::test() @@ -837,7 +841,7 @@ void registerTestCaseFunction /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif @@ -927,22 +931,24 @@ namespace Catch { template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); - private: - DecomposedExpression& operator = (DecomposedExpression const&); + private: + DecomposedExpression& operator = (DecomposedExpression const&); }; struct AssertionInfo { - AssertionInfo() {} - AssertionInfo( std::string const& _macroName, + AssertionInfo(); + AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ); + char const * _capturedExpression, + ResultDisposition::Flags _resultDisposition, + char const * _secondArg = ""); - std::string macroName; + char const * macroName; SourceLineInfo lineInfo; - std::string capturedExpression; + char const * capturedExpression; ResultDisposition::Flags resultDisposition; + char const * secondArg; }; struct AssertionResultData @@ -1156,23 +1162,23 @@ namespace Matchers { // This allows the types to be inferred // - deprecated: prefer ||, && and ! template<typename T> - inline Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) { + Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) { return Impl::MatchNotOf<T>( underlyingMatcher ); } template<typename T> - inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { + Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { return Impl::MatchAllOf<T>() && m1 && m2; } template<typename T> - inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { + Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { return Impl::MatchAllOf<T>() && m1 && m2 && m3; } template<typename T> - inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { + Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { return Impl::MatchAnyOf<T>() || m1 || m2; } template<typename T> - inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { + Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { return Impl::MatchAnyOf<T>() || m1 || m2 || m3; } @@ -1217,7 +1223,7 @@ namespace Catch { template<typename T> ResultBuilder& operator << ( T const& value ) { - m_stream.oss << value; + stream().oss << value; return *this; } @@ -1250,11 +1256,27 @@ namespace Catch { private: AssertionInfo m_assertionInfo; AssertionResultData m_data; - CopyableStream m_stream; + + CopyableStream &stream() + { + if(!m_usedStream) + { + m_usedStream = true; + m_stream().oss.str(""); + } + return m_stream(); + } + + static CopyableStream &m_stream() + { + static CopyableStream s; + return s; + } bool m_shouldDebugBreak; bool m_shouldThrow; bool m_guardException; + bool m_usedStream; }; } // namespace Catch @@ -1295,7 +1317,7 @@ namespace Internal { template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; template<typename T> - inline T& opCast(T const& t) { return const_cast<T&>(t); } + T& opCast(T const& t) { return const_cast<T&>(t); } // nullptr_t support based on pull request #154 from Konstantin Baumann #ifdef CATCH_CONFIG_CPP11_NULLPTR @@ -1305,7 +1327,7 @@ namespace Internal { // So the compare overloads can be operator agnostic we convey the operator as a template // enum, which is used to specialise an Evaluator for doing the comparison. template<typename T1, typename T2, Operator Op> - class Evaluator{}; + struct Evaluator{}; template<typename T1, typename T2> struct Evaluator<T1, T2, IsEqualTo> { @@ -1571,7 +1593,7 @@ std::string toString( std::nullptr_t ); #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ); - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG & nsstring ); std::string toString( NSObject* const& nsObject ); #endif @@ -1660,7 +1682,7 @@ namespace Detail { std::string rawMemoryToString( const void *object, std::size_t size ); template<typename T> - inline std::string rawMemoryToString( const T& object ) { + std::string rawMemoryToString( const T& object ) { return rawMemoryToString( &object, sizeof(object) ); } @@ -1855,7 +1877,7 @@ public: } virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { - dest = Catch::toString( m_truthy ); + dest = Catch::toString( m_lhs ); } private: @@ -1949,7 +1971,7 @@ private: namespace Catch { template<typename T> - inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) { + ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) { return ExpressionLhs<T const&>( *this, operand ); } @@ -1958,7 +1980,7 @@ namespace Catch { } template<typename ArgT, typename MatcherT> - inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, + void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ) { MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString ); setResultType( matcher.match( arg ) ); @@ -2057,6 +2079,10 @@ namespace Catch { virtual void exceptionEarlyReported() = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + virtual void assertionRun() = 0; }; IResultCapture& getResultCapture(); @@ -2099,9 +2125,9 @@ namespace Catch{ #if defined(__ppc64__) || defined(__ppc__) #define CATCH_TRAP() \ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ - : : : "memory","r0","r3","r4" ) + : : : "memory","r0","r3","r4" ) /* NOLINT */ #else - #define CATCH_TRAP() __asm__("int $3\n" : : ) + #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) #endif #elif defined(CATCH_PLATFORM_LINUX) @@ -2109,7 +2135,7 @@ namespace Catch{ // directly at the location of the failing check instead of breaking inside // raise() called from it, i.e. one stack frame below. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) - #define CATCH_TRAP() asm volatile ("int $3") + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ #else // Fall back to the generic way. #include <signal.h> @@ -2204,12 +2230,12 @@ namespace Catch { /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( Catch::getResultCapture().getLastResult()->succeeded() ) + if( Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( !Catch::getResultCapture().getLastResult()->succeeded() ) + if( !Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ @@ -2769,13 +2795,6 @@ namespace Detail { m_value( value ) {} - Approx( Approx const& other ) - : m_epsilon( other.m_epsilon ), - m_margin( other.m_margin ), - m_scale( other.m_scale ), - m_value( other.m_value ) - {} - static Approx custom() { return Approx( 0 ); } @@ -3490,16 +3509,16 @@ return @ desc; \ #include <crtdbg.h> class LeakDetector { public: - LeakDetector() { - int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - flag |= _CRTDBG_LEAK_CHECK_DF; - flag |= _CRTDBG_ALLOC_MEM_DF; - _CrtSetDbgFlag(flag); - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - // Change this to leaking allocation's number to break there - _CrtSetBreakAlloc(-1); - } + LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } }; #else class LeakDetector {}; @@ -3699,7 +3718,7 @@ namespace Catch { ITagAliasRegistry const* m_tagAliases; public: - TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {} TestSpecParser& parse( std::string const& arg ) { m_mode = None; @@ -3883,6 +3902,7 @@ namespace Catch { std::ostream& cout(); std::ostream& cerr(); + std::ostream& clog(); struct IStream { virtual ~IStream() CATCH_NOEXCEPT; @@ -3938,6 +3958,7 @@ namespace Catch { listTags( false ), listReporters( false ), listTestNamesOnly( false ), + listExtraInfo( false ), showSuccessfulTests( false ), shouldDebugBreak( false ), noThrow( false ), @@ -3957,6 +3978,7 @@ namespace Catch { bool listTags; bool listReporters; bool listTestNamesOnly; + bool listExtraInfo; bool showSuccessfulTests; bool shouldDebugBreak; @@ -4015,6 +4037,7 @@ namespace Catch { bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } bool listTags() const { return m_data.listTags; } bool listReporters() const { return m_data.listReporters; } + bool listExtraInfo() const { return m_data.listExtraInfo; } std::string getProcessName() const { return m_data.processName; } @@ -4212,7 +4235,7 @@ namespace Tbc { return oss.str(); } - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) @@ -5276,6 +5299,10 @@ namespace Catch { .describe( "list all/matching test cases names only" ) .bind( &ConfigData::listTestNamesOnly ); + cli["--list-extra-info"] + .describe( "list all/matching test cases with more info" ) + .bind( &ConfigData::listExtraInfo ); + cli["--list-reporters"] .describe( "list all reporters" ) .bind( &ConfigData::listReporters ); @@ -5804,8 +5831,9 @@ namespace Catch { } std::size_t matchedTests = 0; - TextAttributes nameAttr, tagsAttr; + TextAttributes nameAttr, descAttr, tagsAttr; nameAttr.setInitialIndent( 2 ).setIndent( 4 ); + descAttr.setIndent( 4 ); tagsAttr.setIndent( 6 ); std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); @@ -5820,6 +5848,13 @@ namespace Catch { Colour colourGuard( colour ); Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; + if( config.listExtraInfo() ) { + Catch::cout() << " " << testCaseInfo.lineInfo << std::endl; + std::string description = testCaseInfo.description; + if( description.empty() ) + description = "(NO DESCRIPTION)"; + Catch::cout() << Text( description, descAttr ) << std::endl; + } if( !testCaseInfo.tags.empty() ) Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; } @@ -5843,9 +5878,12 @@ namespace Catch { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); if( startsWith( testCaseInfo.name, '#' ) ) - Catch::cout() << '"' << testCaseInfo.name << '"' << std::endl; + Catch::cout() << '"' << testCaseInfo.name << '"'; else - Catch::cout() << testCaseInfo.name << std::endl; + Catch::cout() << testCaseInfo.name; + if ( config.listExtraInfo() ) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; } return matchedTests; } @@ -5937,7 +5975,7 @@ namespace Catch { inline Option<std::size_t> list( Config const& config ) { Option<std::size_t> listedCount; - if( config.listTests() ) + if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) listedCount = listedCount.valueOr(0) + listTests( config ); if( config.listTestNamesOnly() ) listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); @@ -6549,6 +6587,29 @@ namespace Catch { std::string& m_targetString; }; + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes and cannot use StreamRedirect on its own + class StdErrRedirect { + public: + StdErrRedirect(std::string& targetString) + :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), + m_targetString(targetString){ + cerr().rdbuf(m_oss.rdbuf()); + clog().rdbuf(m_oss.rdbuf()); + } + ~StdErrRedirect() { + m_targetString += m_oss.str(); + cerr().rdbuf(m_cerrBuf); + clog().rdbuf(m_clogBuf); + } + private: + std::streambuf* m_cerrBuf; + std::streambuf* m_clogBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + /////////////////////////////////////////////////////////////////////////// class RunContext : public IResultCapture, public IRunner { @@ -6647,10 +6708,27 @@ namespace Catch { static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); // Reset working state - m_lastAssertionInfo = AssertionInfo( std::string(), m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastResult = result; } + virtual bool lastAssertionPassed() + { + return m_totals.assertions.passed == (m_prevPassed + 1); + } + + virtual void assertionPassed() + { + m_totals.assertions.passed++; + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; + m_lastAssertionInfo.macroName = ""; + } + + virtual void assertionRun() + { + m_prevPassed = m_totals.assertions.passed; + } + virtual bool sectionStarted ( SectionInfo const& sectionInfo, Counts& assertions @@ -6751,6 +6829,7 @@ namespace Catch { Totals deltaTotals; deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, std::string(), @@ -6777,7 +6856,7 @@ namespace Catch { double duration = 0; m_shouldReportUnexpected = true; try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, std::string(), ResultDisposition::Normal ); + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); seedRng( *m_config ); @@ -6785,7 +6864,7 @@ namespace Catch { timer.start(); if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( Catch::cout(), redirectedCout ); - StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); + StdErrRedirect errRedir( redirectedCerr ); invokeActiveTestCase(); } else { @@ -6829,9 +6908,9 @@ namespace Catch { private: ResultBuilder makeUnexpectedResultBuilder() const { - return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), + return ResultBuilder( m_lastAssertionInfo.macroName, m_lastAssertionInfo.lineInfo, - m_lastAssertionInfo.capturedExpression.c_str(), + m_lastAssertionInfo.capturedExpression, m_lastAssertionInfo.resultDisposition ); } @@ -6861,6 +6940,7 @@ namespace Catch { std::vector<SectionEndInfo> m_unfinishedSections; std::vector<ITracker*> m_activeSections; TrackerContext m_trackerContext; + size_t m_prevPassed; bool m_shouldReportUnexpected; }; @@ -6919,10 +6999,14 @@ namespace Catch { return reporter; } +#if !defined(CATCH_CONFIG_DEFAULT_REPORTER) +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) { std::vector<std::string> reporters = config->getReporterNames(); if( reporters.empty() ) - reporters.push_back( "console" ); + reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER ); Ptr<IStreamingReporter> reporter; for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end(); @@ -6982,11 +7066,11 @@ namespace Catch { if( lastSlash != std::string::npos ) filename = filename.substr( lastSlash+1 ); - std::string::size_type lastDot = filename.find_last_of( "." ); + std::string::size_type lastDot = filename.find_last_of( '.' ); if( lastDot != std::string::npos ) filename = filename.substr( 0, lastDot ); - tags.insert( "#" + filename ); + tags.insert( '#' + filename ); setTags( test, tags ); } } @@ -7638,6 +7722,9 @@ namespace Catch { std::ostream& cerr() { return std::cerr; } + std::ostream& clog() { + return std::clog; + } #endif } @@ -8008,14 +8095,18 @@ namespace Catch { namespace Catch { - AssertionInfo::AssertionInfo( std::string const& _macroName, + AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){} + + AssertionInfo::AssertionInfo( char const * _macroName, SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ) + char const * _capturedExpression, + ResultDisposition::Flags _resultDisposition, + char const * _secondArg) : macroName( _macroName ), lineInfo( _lineInfo ), capturedExpression( _capturedExpression ), - resultDisposition( _resultDisposition ) + resultDisposition( _resultDisposition ), + secondArg( _secondArg ) {} AssertionResult::AssertionResult() {} @@ -8042,24 +8133,30 @@ namespace Catch { } bool AssertionResult::hasExpression() const { - return !m_info.capturedExpression.empty(); + return m_info.capturedExpression[0] != 0; } bool AssertionResult::hasMessage() const { return !m_resultData.message.empty(); } + std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) { + return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"') + ? capturedExpression + : std::string(capturedExpression) + ", " + secondArg; + } + std::string AssertionResult::getExpression() const { if( isFalseTest( m_info.resultDisposition ) ) - return '!' + m_info.capturedExpression; + return '!' + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); else - return m_info.capturedExpression; + return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); } std::string AssertionResult::getExpressionInMacro() const { - if( m_info.macroName.empty() ) - return m_info.capturedExpression; + if( m_info.macroName[0] == 0 ) + return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); else - return m_info.macroName + "( " + m_info.capturedExpression + " )"; + return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )"; } bool AssertionResult::hasExpandedExpression() const { @@ -8309,7 +8406,7 @@ namespace Catch { } inline Version libraryVersion() { - static Version version( 1, 9, 4, "", 0 ); + static Version version( 1, 9, 7, "", 0 ); return version; } @@ -8661,6 +8758,10 @@ namespace Catch { m_timer.start(); } +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 +#endif Section::~Section() { if( m_sectionIncluded ) { SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); @@ -8670,6 +8771,9 @@ namespace Catch { getResultCapture().sectionEnded( endInfo ); } } +#if defined(_MSC_VER) +#pragma warning(pop) +#endif // This indicates whether the section should be executed or not Section::operator bool() const { @@ -8985,7 +9089,7 @@ std::string toString( std::nullptr_t ) { return "nil"; return "@" + toString([nsstring UTF8String]); } - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { + std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); @@ -9002,26 +9106,22 @@ std::string toString( std::nullptr_t ) { namespace Catch { - std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { - return secondArg.empty() || secondArg == "\"\"" - ? capturedExpression - : capturedExpression + ", " + secondArg; - } ResultBuilder::ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg ) - : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), + : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), m_shouldDebugBreak( false ), m_shouldThrow( false ), - m_guardException( false ) + m_guardException( false ), + m_usedStream( false ) {} ResultBuilder::~ResultBuilder() { #if defined(CATCH_CONFIG_FAST_COMPILE) if ( m_guardException ) { - m_stream.oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; captureResult( ResultWas::ThrewException ); getCurrentContext().getResultCapture()->exceptionEarlyReported(); } @@ -9038,13 +9138,25 @@ namespace Catch { } void ResultBuilder::endExpression( DecomposedExpression const& expr ) { - AssertionResult result = build( expr ); - handleResult( result ); + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + m_data.negate( expr.isBinaryExpression() ); + } + + getResultCapture().assertionRun(); + + if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) + { + AssertionResult result = build( expr ); + handleResult( result ); + } + else + getResultCapture().assertionPassed(); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { m_assertionInfo.resultDisposition = resultDisposition; - m_stream.oss << Catch::translateActiveException(); + stream().oss << Catch::translateActiveException(); captureResult( ResultWas::ThrewException ); } @@ -9065,7 +9177,7 @@ namespace Catch { assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); AssertionResultData data = m_data; data.resultType = ResultWas::Ok; - data.reconstructedExpression = m_assertionInfo.capturedExpression; + data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); std::string actualMessage = Catch::translateActiveException(); if( !matcher.match( actualMessage ) ) { @@ -9126,18 +9238,14 @@ namespace Catch { assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; - // Flip bool results if FalseTest flag is set - if( isFalseTest( m_assertionInfo.resultDisposition ) ) { - data.negate( expr.isBinaryExpression() ); - } - - data.message = m_stream.oss.str(); + if(m_usedStream) + data.message = m_stream().oss.str(); data.decomposedExpression = &expr; // for lazy reconstruction return AssertionResult( m_assertionInfo, data ); } void ResultBuilder::reconstructExpression( std::string& dest ) const { - dest = m_assertionInfo.capturedExpression; + dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); } void ResultBuilder::setExceptionGuard() { @@ -9560,7 +9668,8 @@ namespace Catch { BySectionInfo( SectionInfo const& other ) : m_other( other ) {} BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} bool operator() ( Ptr<SectionNode> const& node ) const { - return node->stats.sectionInfo.lineInfo == m_other.lineInfo; + return ((node->stats.sectionInfo.name == m_other.name) && + (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); } private: void operator=( BySectionInfo const& ); @@ -10028,20 +10137,6 @@ namespace Catch { }; } -// #included from: catch_reenable_warnings.h - -#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(pop) -# else -# pragma clang diagnostic pop -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic pop -#endif - namespace Catch { class XmlReporter : public StreamingReporterBase { @@ -10296,6 +10391,7 @@ namespace Catch { JunitReporter( ReporterConfig const& _config ) : CumulativeReporterBase( _config ), xml( _config.stream() ), + unexpectedExceptions( 0 ), m_okToFail( false ) { m_reporterPrefs.shouldRedirectStdOut = true; @@ -11303,7 +11399,7 @@ extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { int main (int argc, char * argv[]) { #endif - int result = Catch::Session().run( argc, argv ); + int result = Catch::Session().run( argc, argv ); return ( result < 0xff ? result : 0xff ); } @@ -11504,5 +11600,19 @@ int main (int argc, char * const argv[]) { using Catch::Detail::Approx; +// #included from: internal/catch_reenable_warnings.h + +#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED |