mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-24 06:16:10 +01:00
Fix assertionStarting events being sent after the expr is evaluated
Closes #2678
This commit is contained in:
parent
51fdbedd13
commit
d84777c9cb
@ -96,12 +96,12 @@ void assertionStarting( AssertionInfo const& assertionInfo );
|
|||||||
void assertionEnded( AssertionStats const& assertionStats );
|
void assertionEnded( AssertionStats const& assertionStats );
|
||||||
```
|
```
|
||||||
|
|
||||||
`assertionStarting` is called after the expression is captured, but before
|
The `assertionStarting` event is emitted before the expression in the
|
||||||
the assertion expression is evaluated. This might seem like a minor
|
assertion is captured or evaluated and `assertionEnded` is emitted
|
||||||
distinction, but what it means is that if you have assertion like
|
afterwards. This means that given assertion like `REQUIRE(a + b == c + d)`,
|
||||||
`REQUIRE( a + b == c + d )`, then what happens is that `a + b` and `c + d`
|
Catch2 first emits `assertionStarting` event, then `a + b` and `c + d`
|
||||||
are evaluated before `assertionStarting` is emitted, while the `==` is
|
are evaluated, then their results are captured, the comparison is evaluated,
|
||||||
evaluated after the event.
|
and then `assertionEnded` event is emitted.
|
||||||
|
|
||||||
|
|
||||||
## Benchmarking events
|
## Benchmarking events
|
||||||
|
@ -43,6 +43,7 @@ namespace Catch {
|
|||||||
public:
|
public:
|
||||||
virtual ~IResultCapture();
|
virtual ~IResultCapture();
|
||||||
|
|
||||||
|
virtual void notifyAssertionStarted( AssertionInfo const& info ) = 0;
|
||||||
virtual bool sectionStarted( StringRef sectionName,
|
virtual bool sectionStarted( StringRef sectionName,
|
||||||
SourceLineInfo const& sectionLineInfo,
|
SourceLineInfo const& sectionLineInfo,
|
||||||
Counts& assertions ) = 0;
|
Counts& assertions ) = 0;
|
||||||
|
@ -23,7 +23,9 @@ namespace Catch {
|
|||||||
ResultDisposition::Flags resultDisposition )
|
ResultDisposition::Flags resultDisposition )
|
||||||
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
|
: m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },
|
||||||
m_resultCapture( getResultCapture() )
|
m_resultCapture( getResultCapture() )
|
||||||
{}
|
{
|
||||||
|
m_resultCapture.notifyAssertionStarted( m_assertionInfo );
|
||||||
|
}
|
||||||
|
|
||||||
void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
|
void AssertionHandler::handleExpr( ITransientExpression const& expr ) {
|
||||||
m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
|
m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );
|
||||||
|
@ -301,7 +301,13 @@ namespace Catch {
|
|||||||
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
|
m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RunContext::sectionStarted(StringRef sectionName, SourceLineInfo const& sectionLineInfo, Counts & assertions) {
|
void RunContext::notifyAssertionStarted( AssertionInfo const& info ) {
|
||||||
|
m_reporter->assertionStarting( info );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunContext::sectionStarted( StringRef sectionName,
|
||||||
|
SourceLineInfo const& sectionLineInfo,
|
||||||
|
Counts& assertions ) {
|
||||||
ITracker& sectionTracker =
|
ITracker& sectionTracker =
|
||||||
SectionTracker::acquire( m_trackerContext,
|
SectionTracker::acquire( m_trackerContext,
|
||||||
TestCaseTracking::NameAndLocationRef(
|
TestCaseTracking::NameAndLocationRef(
|
||||||
@ -561,8 +567,6 @@ namespace Catch {
|
|||||||
ITransientExpression const& expr,
|
ITransientExpression const& expr,
|
||||||
AssertionReaction& reaction
|
AssertionReaction& reaction
|
||||||
) {
|
) {
|
||||||
m_reporter->assertionStarting( info );
|
|
||||||
|
|
||||||
bool negated = isFalseTest( info.resultDisposition );
|
bool negated = isFalseTest( info.resultDisposition );
|
||||||
bool result = expr.getResult() != negated;
|
bool result = expr.getResult() != negated;
|
||||||
|
|
||||||
@ -600,8 +604,6 @@ namespace Catch {
|
|||||||
StringRef message,
|
StringRef message,
|
||||||
AssertionReaction& reaction
|
AssertionReaction& reaction
|
||||||
) {
|
) {
|
||||||
m_reporter->assertionStarting( info );
|
|
||||||
|
|
||||||
m_lastAssertionInfo = info;
|
m_lastAssertionInfo = info;
|
||||||
|
|
||||||
AssertionResultData data( resultType, LazyExpression( false ) );
|
AssertionResultData data( resultType, LazyExpression( false ) );
|
||||||
|
@ -70,6 +70,7 @@ namespace Catch {
|
|||||||
ResultWas::OfType resultType,
|
ResultWas::OfType resultType,
|
||||||
AssertionReaction &reaction ) override;
|
AssertionReaction &reaction ) override;
|
||||||
|
|
||||||
|
void notifyAssertionStarted( AssertionInfo const& info ) override;
|
||||||
bool sectionStarted( StringRef sectionName,
|
bool sectionStarted( StringRef sectionName,
|
||||||
SourceLineInfo const& sectionLineInfo,
|
SourceLineInfo const& sectionLineInfo,
|
||||||
Counts& assertions ) override;
|
Counts& assertions ) override;
|
||||||
|
@ -468,6 +468,17 @@ set_tests_properties(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(AssertionStartingEventGoesBeforeAssertionIsEvaluated
|
||||||
|
X20-AssertionStartingEventGoesBeforeAssertionIsEvaluated.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(AssertionStartingEventGoesBeforeAssertionIsEvaluated
|
||||||
|
PRIVATE Catch2::Catch2WithMain
|
||||||
|
)
|
||||||
|
add_test(
|
||||||
|
NAME ReporterEvents::AssertionStartingHappensBeforeAssertionIsEvaluated
|
||||||
|
COMMAND $<TARGET_FILE:AssertionStartingEventGoesBeforeAssertionIsEvaluated>
|
||||||
|
)
|
||||||
|
|
||||||
#add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
|
#add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
|
||||||
#target_link_libraries(DebugBreakMacros Catch2)
|
#target_link_libraries(DebugBreakMacros Catch2)
|
||||||
#add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)
|
#add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
// Copyright Catch2 Authors
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE.txt or copy at
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
|
/**\file
|
||||||
|
* TODO: FIXES Registers custom reporter that reports testCase* events
|
||||||
|
*
|
||||||
|
* The resulting executable can then be used by an external Python script
|
||||||
|
* to verify that testCase{Starting,Ended} and testCasePartial{Starting,Ended}
|
||||||
|
* events are properly nested.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/reporters/catch_reporter_event_listener.hpp>
|
||||||
|
#include <catch2/reporters/catch_reporter_registrars.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_predicate.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static size_t assertion_starting_events_seen = 0;
|
||||||
|
|
||||||
|
// TODO: custom matcher to check that "assertion_starting_events_seen" has
|
||||||
|
// the right number of checks
|
||||||
|
|
||||||
|
class AssertionStartingListener : public Catch::EventListenerBase {
|
||||||
|
public:
|
||||||
|
AssertionStartingListener( Catch::IConfig const* config ):
|
||||||
|
EventListenerBase( config ) {}
|
||||||
|
|
||||||
|
void assertionStarting( Catch::AssertionInfo const& ) override {
|
||||||
|
++assertion_starting_events_seen;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool f1() {
|
||||||
|
return assertion_starting_events_seen == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f2() {
|
||||||
|
if ( assertion_starting_events_seen != 2 ) { throw 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f3() {
|
||||||
|
if ( assertion_starting_events_seen == 3 ) { throw 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool f4() { return assertion_starting_events_seen == 4; }
|
||||||
|
|
||||||
|
static void f5() { throw assertion_starting_events_seen; }
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
CATCH_REGISTER_LISTENER( AssertionStartingListener )
|
||||||
|
|
||||||
|
TEST_CASE() {
|
||||||
|
// **IMPORTANT**
|
||||||
|
// The order of assertions below matters.
|
||||||
|
REQUIRE( f1() );
|
||||||
|
REQUIRE_NOTHROW( f2() );
|
||||||
|
REQUIRE_THROWS( f3() );
|
||||||
|
REQUIRE_THAT( f4(),
|
||||||
|
Catch::Matchers::Predicate<bool>( []( bool b ) { return b; } ) );
|
||||||
|
REQUIRE_THROWS_MATCHES(
|
||||||
|
f5(), size_t, Catch::Matchers::Predicate<size_t>( []( size_t i ) {
|
||||||
|
return i == 5;
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
CAPTURE( assertion_starting_events_seen ); // **not** an assertion
|
||||||
|
INFO( "some info msg" ); // **not** an assertion
|
||||||
|
WARN( "warning! warning!" ); // assertion-like message
|
||||||
|
SUCCEED(); // assertion-like message
|
||||||
|
|
||||||
|
// We skip FAIL/SKIP and so on, which fail the test.
|
||||||
|
|
||||||
|
// This require will also increment the count once
|
||||||
|
REQUIRE( assertion_starting_events_seen == 8 );
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user