diff --git a/src/catch2/internal/catch_run_context.cpp b/src/catch2/internal/catch_run_context.cpp index 37045f60..1ecc0644 100644 --- a/src/catch2/internal/catch_run_context.cpp +++ b/src/catch2/internal/catch_run_context.cpp @@ -824,6 +824,14 @@ namespace Catch { } void IResultCapture::emplaceUnscopedMessage( MessageBuilder&& builder ) { + // Invalid unscoped messages are lazy cleared. If we have any, + // we have to get rid of them before adding new ones, or the + // delayed clear in assertion handling will erase the valid ones + // as well. + if ( Detail::g_clearMessageScopes ) { + Detail::g_messageScopes.clear(); + Detail::g_clearMessageScopes = false; + } Detail::g_messageScopes.emplace_back( CATCH_MOVE( builder ) ); } diff --git a/tests/ExtraTests/CMakeLists.txt b/tests/ExtraTests/CMakeLists.txt index fbcc3465..e7965fa9 100644 --- a/tests/ExtraTests/CMakeLists.txt +++ b/tests/ExtraTests/CMakeLists.txt @@ -177,6 +177,18 @@ set_tests_properties(DeferredStaticChecks PASS_REGULAR_EXPRESSION "test cases: 1 \\| 1 failed\nassertions: 3 \\| 3 failed" ) +add_executable(MixingClearedAndUnclearedMessages ${TESTS_DIR}/X06-MixingClearedAndUnclearedMessages.cpp) +target_link_libraries(MixingClearedAndUnclearedMessages PRIVATE Catch2WithMain) + +add_test(NAME MixingClearedAndUnclearedMessages + COMMAND + MixingClearedAndUnclearedMessages + -r compact) +set_tests_properties(MixingClearedAndUnclearedMessages + PROPERTIES + PASS_REGULAR_EXPRESSION ": false with 1 message: 'b'" +) + add_executable(FallbackStringifier ${TESTS_DIR}/X10-FallbackStringifier.cpp) target_compile_definitions(FallbackStringifier PRIVATE CATCH_CONFIG_FALLBACK_STRINGIFIER=fallbackStringifier) target_link_libraries(FallbackStringifier Catch2WithMain) @@ -528,6 +540,7 @@ set(EXTRA_TEST_BINARIES DuplicatedTestCases-DuplicatedTestCaseMethods NoTests ListenersGetEventsBeforeReporters + MixingClearedAndUnclearedMessages # DebugBreakMacros ) diff --git a/tests/ExtraTests/X06-MixingClearedAndUnclearedMessages.cpp b/tests/ExtraTests/X06-MixingClearedAndUnclearedMessages.cpp new file mode 100644 index 00000000..2c52ba1b --- /dev/null +++ b/tests/ExtraTests/X06-MixingClearedAndUnclearedMessages.cpp @@ -0,0 +1,27 @@ + +// 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 + * Checks that when we use up an unscoped message (e.g. `UNSCOPED_INFO`), + * with an assertion, and then add another message later, it will be + * properly reported with later failing assertion. + * + * This needs separate binary to avoid the main test binary's validating + * listener, which disables the assertion fast path. + */ + +#include + +TEST_CASE( + "Delayed unscoped message clearing does not catch newly inserted messages", + "[messages][unscoped][!shouldfail]" ) { + UNSCOPED_INFO( "a" ); + REQUIRE( true ); + UNSCOPED_INFO( "b" ); + REQUIRE( false ); +} diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 4a6886d6..6b0ac614 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -138,6 +138,7 @@ Nor would this :test-result: FAIL Custom exceptions can be translated when testing for throwing as something else :test-result: FAIL Custom std-exceptions can be custom translated :test-result: PASS Default scale is invisible to comparison +:test-result: XFAIL Delayed unscoped message clearing does not catch newly inserted messages :test-result: PASS Directly creating an EnumInfo :test-result: SKIP Empty generators can SKIP in constructor :test-result: PASS Empty stream name opens cout stream diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt index b0d30b87..54d1c58f 100644 --- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt @@ -136,6 +136,7 @@ :test-result: FAIL Custom exceptions can be translated when testing for throwing as something else :test-result: FAIL Custom std-exceptions can be custom translated :test-result: PASS Default scale is invisible to comparison +:test-result: XFAIL Delayed unscoped message clearing does not catch newly inserted messages :test-result: PASS Directly creating an EnumInfo :test-result: SKIP Empty generators can SKIP in constructor :test-result: PASS Empty stream name opens cout stream diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index cacb898a..37c2624f 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -562,6 +562,8 @@ Exception.tests.cpp:: failed: unexpected exception with message: 'c Exception.tests.cpp:: failed: unexpected exception with message: 'custom std exception' Approx.tests.cpp:: passed: 101.000001 != Approx(100).epsilon(0.01) for: 101.00000099999999748 != Approx( 100.0 ) Approx.tests.cpp:: passed: std::pow(10, -5) != Approx(std::pow(10, -7)) for: 0.00001 != Approx( 0.0000001 ) +Message.tests.cpp:: passed: true with 1 message: 'a' +Message.tests.cpp:: failed: false with 1 message: 'b' ToString.tests.cpp:: passed: enumInfo->lookup(0) == "Value1" for: Value1 == "Value1" ToString.tests.cpp:: passed: enumInfo->lookup(1) == "Value2" for: Value2 == "Value2" ToString.tests.cpp:: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} @@ -2888,7 +2890,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected +assertions: 2305 | 2106 passed | 157 failed | 42 failed as expected diff --git a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt index 10395c9a..b103d28f 100644 --- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt @@ -560,6 +560,8 @@ Exception.tests.cpp:: failed: unexpected exception with message: 'c Exception.tests.cpp:: failed: unexpected exception with message: 'custom std exception' Approx.tests.cpp:: passed: 101.000001 != Approx(100).epsilon(0.01) for: 101.00000099999999748 != Approx( 100.0 ) Approx.tests.cpp:: passed: std::pow(10, -5) != Approx(std::pow(10, -7)) for: 0.00001 != Approx( 0.0000001 ) +Message.tests.cpp:: passed: true with 1 message: 'a' +Message.tests.cpp:: failed: false with 1 message: 'b' ToString.tests.cpp:: passed: enumInfo->lookup(0) == "Value1" for: Value1 == "Value1" ToString.tests.cpp:: passed: enumInfo->lookup(1) == "Value2" for: Value2 == "Value2" ToString.tests.cpp:: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} @@ -2877,7 +2879,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0 InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected +assertions: 2305 | 2106 passed | 157 failed | 42 failed as expected diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index c1512db5..eefaa889 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -450,6 +450,17 @@ Exception.tests.cpp:: FAILED: due to unexpected exception with message: custom std exception +------------------------------------------------------------------------------- +Delayed unscoped message clearing does not catch newly inserted messages +------------------------------------------------------------------------------- +Message.tests.cpp: +............................................................................... + +Message.tests.cpp:: FAILED: + REQUIRE( false ) +with message: + b + ------------------------------------------------------------------------------- Empty generators can SKIP in constructor ------------------------------------------------------------------------------- @@ -1719,6 +1730,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 435 | 335 passed | 76 failed | 7 skipped | 17 failed as expected -assertions: 2282 | 2105 passed | 136 failed | 41 failed as expected +test cases: 436 | 335 passed | 76 failed | 7 skipped | 18 failed as expected +assertions: 2284 | 2106 passed | 136 failed | 42 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index 7fd59514..5b82e70e 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -4148,6 +4148,22 @@ Approx.tests.cpp:: PASSED: with expansion: 0.00001 != Approx( 0.0000001 ) +------------------------------------------------------------------------------- +Delayed unscoped message clearing does not catch newly inserted messages +------------------------------------------------------------------------------- +Message.tests.cpp: +............................................................................... + +Message.tests.cpp:: PASSED: + REQUIRE( true ) +with message: + a + +Message.tests.cpp:: FAILED: + REQUIRE( false ) +with message: + b + ------------------------------------------------------------------------------- Directly creating an EnumInfo ------------------------------------------------------------------------------- @@ -19295,6 +19311,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected +assertions: 2305 | 2106 passed | 157 failed | 42 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt index 08ab1b2b..61873e2f 100644 --- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -4146,6 +4146,22 @@ Approx.tests.cpp:: PASSED: with expansion: 0.00001 != Approx( 0.0000001 ) +------------------------------------------------------------------------------- +Delayed unscoped message clearing does not catch newly inserted messages +------------------------------------------------------------------------------- +Message.tests.cpp: +............................................................................... + +Message.tests.cpp:: PASSED: + REQUIRE( true ) +with message: + a + +Message.tests.cpp:: FAILED: + REQUIRE( false ) +with message: + b + ------------------------------------------------------------------------------- Directly creating an EnumInfo ------------------------------------------------------------------------------- @@ -19284,6 +19300,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected -assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected +test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected +assertions: 2305 | 2106 passed | 157 failed | 42 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index c12b6178..ea99ab45 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -547,6 +547,15 @@ at Exception.tests.cpp: + + + +FAILED: + REQUIRE( false ) +b +at Message.tests.cpp: + + diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt index e844ca6c..07e402c7 100644 --- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt @@ -1,6 +1,6 @@ - + @@ -546,6 +546,15 @@ at Exception.tests.cpp: + + + +FAILED: + REQUIRE( false ) +b +at Message.tests.cpp: + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index d79abd37..881851c3 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -1699,6 +1699,14 @@ at Message.tests.cpp: + + +FAILED: + REQUIRE( false ) +b +at Message.tests.cpp: + + FAILED: diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt index 98a06c14..5a64789d 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt @@ -1698,6 +1698,14 @@ at Message.tests.cpp: + + +FAILED: + REQUIRE( false ) +b +at Message.tests.cpp: + + FAILED: diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index 3e5d1832..415f9964 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -1024,6 +1024,10 @@ not ok {test-number} - unexpected exception with message: 'custom std exception' ok {test-number} - 101.000001 != Approx(100).epsilon(0.01) for: 101.00000099999999748 != Approx( 100.0 ) # Default scale is invisible to comparison ok {test-number} - std::pow(10, -5) != Approx(std::pow(10, -7)) for: 0.00001 != Approx( 0.0000001 ) +# Delayed unscoped message clearing does not catch newly inserted messages +ok {test-number} - true with 1 message: 'a' +# Delayed unscoped message clearing does not catch newly inserted messages +not ok {test-number} - false with 1 message: 'b' # Directly creating an EnumInfo ok {test-number} - enumInfo->lookup(0) == "Value1" for: Value1 == "Value1" # Directly creating an EnumInfo @@ -4627,5 +4631,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2315 +1..2317 diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index 0fdb266a..63ea617b 100644 --- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -1022,6 +1022,10 @@ not ok {test-number} - unexpected exception with message: 'custom std exception' ok {test-number} - 101.000001 != Approx(100).epsilon(0.01) for: 101.00000099999999748 != Approx( 100.0 ) # Default scale is invisible to comparison ok {test-number} - std::pow(10, -5) != Approx(std::pow(10, -7)) for: 0.00001 != Approx( 0.0000001 ) +# Delayed unscoped message clearing does not catch newly inserted messages +ok {test-number} - true with 1 message: 'a' +# Delayed unscoped message clearing does not catch newly inserted messages +not ok {test-number} - false with 1 message: 'b' # Directly creating an EnumInfo ok {test-number} - enumInfo->lookup(0) == "Value1" for: Value1 == "Value1" # Directly creating an EnumInfo @@ -4616,5 +4620,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2315 +1..2317 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index 853f3d80..e911941c 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -322,6 +322,9 @@ ##teamcity[testFinished name='Custom std-exceptions can be custom translated' duration="{duration}"] ##teamcity[testStarted name='Default scale is invisible to comparison'] ##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"] +##teamcity[testStarted name='Delayed unscoped message clearing does not catch newly inserted messages'] +##teamcity[testIgnored name='Delayed unscoped message clearing does not catch newly inserted messages' message='Message.tests.cpp:|n...............................................................................|n|nMessage.tests.cpp:|nexpression failed with message:|n "b"|n REQUIRE( false )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n'] +##teamcity[testFinished name='Delayed unscoped message clearing does not catch newly inserted messages' duration="{duration}"] ##teamcity[testStarted name='Directly creating an EnumInfo'] ##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"] ##teamcity[testStarted name='Empty generators can SKIP in constructor'] diff --git a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt index 10e318de..2c7f78e2 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt @@ -322,6 +322,9 @@ ##teamcity[testFinished name='Custom std-exceptions can be custom translated' duration="{duration}"] ##teamcity[testStarted name='Default scale is invisible to comparison'] ##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"] +##teamcity[testStarted name='Delayed unscoped message clearing does not catch newly inserted messages'] +##teamcity[testIgnored name='Delayed unscoped message clearing does not catch newly inserted messages' message='Message.tests.cpp:|n...............................................................................|n|nMessage.tests.cpp:|nexpression failed with message:|n "b"|n REQUIRE( false )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n'] +##teamcity[testFinished name='Delayed unscoped message clearing does not catch newly inserted messages' duration="{duration}"] ##teamcity[testStarted name='Directly creating an EnumInfo'] ##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"] ##teamcity[testStarted name='Empty generators can SKIP in constructor'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index 142d6620..3536950e 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -4613,6 +4613,31 @@ C + + + a + + + + true + + + true + + + + b + + + + false + + + false + + + + @@ -22324,6 +22349,6 @@ Approx( -1.95996398454005449 ) - - + + diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index 62562332..5242f5c9 100644 --- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -4613,6 +4613,31 @@ C + + + a + + + + true + + + true + + + + b + + + + false + + + false + + + + @@ -22323,6 +22348,6 @@ Approx( -1.95996398454005449 ) - - + + diff --git a/tests/SelfTest/UsageTests/Message.tests.cpp b/tests/SelfTest/UsageTests/Message.tests.cpp index 07d3ee7b..594e8892 100644 --- a/tests/SelfTest/UsageTests/Message.tests.cpp +++ b/tests/SelfTest/UsageTests/Message.tests.cpp @@ -360,3 +360,12 @@ TEST_CASE( "Scoped message applies to all assertions in scope", CHECK( false ); CHECK( false ); } + +TEST_CASE( + "Delayed unscoped message clearing does not catch newly inserted messages", + "[messages][unscoped][!shouldfail]" ) { + UNSCOPED_INFO( "a" ); + REQUIRE( true ); + UNSCOPED_INFO( "b" ); + REQUIRE( false ); +}