mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-26 07:16:10 +01:00
Add unscoped info functionality
This adds UNSCOPED_INFO macro, creating a log message that is stored until the end of next assertion or the end of test case, whichever comes first. These messages are not scoped locally, unlike messages created by INFO macro.
This commit is contained in:
parent
1a03918455
commit
99575b45db
@ -215,6 +215,7 @@
|
|||||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
#endif // CATCH_CONFIG_DISABLE_MATCHERS
|
||||||
|
|
||||||
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
|
#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
|
||||||
|
#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "UNSCOPED_INFO", msg )
|
||||||
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
|
#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
|
||||||
#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
|
#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
|
||||||
|
|
||||||
|
@ -130,6 +130,10 @@
|
|||||||
#define INTERNAL_CATCH_INFO( macroName, log ) \
|
#define INTERNAL_CATCH_INFO( macroName, log ) \
|
||||||
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
|
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
|
||||||
|
Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Although this is matcher-based, it can be used with just a string
|
// Although this is matcher-based, it can be used with just a string
|
||||||
#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
|
#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
|
||||||
|
@ -20,6 +20,7 @@ namespace Catch {
|
|||||||
struct SectionInfo;
|
struct SectionInfo;
|
||||||
struct SectionEndInfo;
|
struct SectionEndInfo;
|
||||||
struct MessageInfo;
|
struct MessageInfo;
|
||||||
|
struct MessageBuilder;
|
||||||
struct Counts;
|
struct Counts;
|
||||||
struct BenchmarkInfo;
|
struct BenchmarkInfo;
|
||||||
struct BenchmarkStats;
|
struct BenchmarkStats;
|
||||||
@ -46,6 +47,8 @@ namespace Catch {
|
|||||||
virtual void pushScopedMessage( MessageInfo const& message ) = 0;
|
virtual void pushScopedMessage( MessageInfo const& message ) = 0;
|
||||||
virtual void popScopedMessage( MessageInfo const& message ) = 0;
|
virtual void popScopedMessage( MessageInfo const& message ) = 0;
|
||||||
|
|
||||||
|
virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;
|
||||||
|
|
||||||
virtual void handleFatalErrorCondition( StringRef message ) = 0;
|
virtual void handleFatalErrorCondition( StringRef message ) = 0;
|
||||||
|
|
||||||
virtual void handleExpr
|
virtual void handleExpr
|
||||||
|
@ -47,14 +47,20 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
ScopedMessage::ScopedMessage( MessageBuilder const& builder )
|
ScopedMessage::ScopedMessage( MessageBuilder const& builder )
|
||||||
: m_info( builder.m_info )
|
: m_info( builder.m_info ), m_moved()
|
||||||
{
|
{
|
||||||
m_info.message = builder.m_stream.str();
|
m_info.message = builder.m_stream.str();
|
||||||
getResultCapture().pushScopedMessage( m_info );
|
getResultCapture().pushScopedMessage( m_info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScopedMessage::ScopedMessage( ScopedMessage&& old )
|
||||||
|
: m_info( old.m_info ), m_moved()
|
||||||
|
{
|
||||||
|
old.m_moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
ScopedMessage::~ScopedMessage() {
|
ScopedMessage::~ScopedMessage() {
|
||||||
if ( !uncaught_exceptions() ){
|
if ( !uncaught_exceptions() && !m_moved ){
|
||||||
getResultCapture().popScopedMessage(m_info);
|
getResultCapture().popScopedMessage(m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,12 @@ namespace Catch {
|
|||||||
class ScopedMessage {
|
class ScopedMessage {
|
||||||
public:
|
public:
|
||||||
explicit ScopedMessage( MessageBuilder const& builder );
|
explicit ScopedMessage( MessageBuilder const& builder );
|
||||||
|
ScopedMessage( ScopedMessage& duplicate ) = delete;
|
||||||
|
ScopedMessage( ScopedMessage&& old );
|
||||||
~ScopedMessage();
|
~ScopedMessage();
|
||||||
|
|
||||||
MessageInfo m_info;
|
MessageInfo m_info;
|
||||||
|
bool m_moved;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Capturer {
|
class Capturer {
|
||||||
|
@ -161,6 +161,9 @@ namespace Catch {
|
|||||||
// and should be let to clear themselves out.
|
// and should be let to clear themselves out.
|
||||||
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
|
static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
|
||||||
|
|
||||||
|
if (result.getResultType() != ResultWas::Warning)
|
||||||
|
m_messageScopes.clear();
|
||||||
|
|
||||||
// Reset working state
|
// Reset working state
|
||||||
resetAssertionInfo();
|
resetAssertionInfo();
|
||||||
m_lastResult = result;
|
m_lastResult = result;
|
||||||
@ -215,6 +218,7 @@ namespace Catch {
|
|||||||
|
|
||||||
m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
|
m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
m_messageScopes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
|
void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {
|
||||||
@ -241,6 +245,10 @@ namespace Catch {
|
|||||||
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
|
m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {
|
||||||
|
m_messageScopes.emplace_back( builder );
|
||||||
|
}
|
||||||
|
|
||||||
std::string RunContext::getCurrentTestName() const {
|
std::string RunContext::getCurrentTestName() const {
|
||||||
return m_activeTestCase
|
return m_activeTestCase
|
||||||
? m_activeTestCase->getTestCaseInfo().name
|
? m_activeTestCase->getTestCaseInfo().name
|
||||||
@ -301,6 +309,7 @@ namespace Catch {
|
|||||||
m_lastAssertionPassed = true;
|
m_lastAssertionPassed = true;
|
||||||
++m_totals.assertions.passed;
|
++m_totals.assertions.passed;
|
||||||
resetAssertionInfo();
|
resetAssertionInfo();
|
||||||
|
m_messageScopes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RunContext::aborting() const {
|
bool RunContext::aborting() const {
|
||||||
@ -352,6 +361,7 @@ namespace Catch {
|
|||||||
m_testCaseTracker->close();
|
m_testCaseTracker->close();
|
||||||
handleUnfinishedSections();
|
handleUnfinishedSections();
|
||||||
m_messages.clear();
|
m_messages.clear();
|
||||||
|
m_messageScopes.clear();
|
||||||
|
|
||||||
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);
|
||||||
m_reporter->sectionEnded(testCaseSectionStats);
|
m_reporter->sectionEnded(testCaseSectionStats);
|
||||||
|
@ -88,6 +88,8 @@ namespace Catch {
|
|||||||
void pushScopedMessage( MessageInfo const& message ) override;
|
void pushScopedMessage( MessageInfo const& message ) override;
|
||||||
void popScopedMessage( MessageInfo const& message ) override;
|
void popScopedMessage( MessageInfo const& message ) override;
|
||||||
|
|
||||||
|
void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
|
||||||
|
|
||||||
std::string getCurrentTestName() const override;
|
std::string getCurrentTestName() const override;
|
||||||
|
|
||||||
const AssertionResult* getLastResult() const override;
|
const AssertionResult* getLastResult() const override;
|
||||||
@ -135,6 +137,7 @@ namespace Catch {
|
|||||||
Totals m_totals;
|
Totals m_totals;
|
||||||
IStreamingReporterPtr m_reporter;
|
IStreamingReporterPtr m_reporter;
|
||||||
std::vector<MessageInfo> m_messages;
|
std::vector<MessageInfo> m_messages;
|
||||||
|
std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
|
||||||
AssertionInfo m_lastAssertionInfo;
|
AssertionInfo m_lastAssertionInfo;
|
||||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||||
std::vector<ITracker*> m_activeSections;
|
std::vector<ITracker*> m_activeSections;
|
||||||
|
Loading…
Reference in New Issue
Block a user