Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMartin Hořeňovský2025-07-21 17:47:59 +0200
committerMartin Hořeňovský2025-07-21 21:50:47 +0200
commit10aef62f21e52e5cd73bf0dc6ac8be35fbc4a798 (patch)
tree6e3bae072a2a0ecbd31f3ec0aab7eac8d673c5af
parent98b4bbb35efc3937b24e1de5559c974bd2578a14 (diff)
downloadcatch3-10aef62f21e52e5cd73bf0dc6ac8be35fbc4a798.tar.gz
Regularize scoped message lifetime to only consider the object's scope
This means that: 1) Scoped messages are always removed at the end of their scope, even if the scope ended due to an exception. 2) Scoped messages outlive section end, if that section's scope is enclosed in their own. Previously neither of these were true, which has led to a number of surprising behaviour, where e.g. this: ```cpp TEST_CASE() { try { INFO( "some info" ); throw std::runtime_error( "ex" ); } catch (std::exception const&) {} REQUIRE( false ); } ``` would print "some info" as the message for the assertion, while this: ```cpp TEST_CASE() { INFO("Hello"); SECTION("dummy") {} REQUIRE(false); } ``` would not print out "Hello" as the message for the assertion. This had an underlying reason, in that it was trying to helpfully keep the messages around in case of unexpected exceptions, so that code like this: ```cpp TEST_CASE() { auto [input, expected] = GENERATE(...); CAPTURE(input); auto result = transform(input); // throws REQUIRE(result == expected); } ``` would report the value of `input` when `transform` throws. However, it was surprising in practice and was causing various issues around handling of messages in other cases. Closes #1759 Closes #2019 Closes #2959
-rw-r--r--docs/logging.md36
-rw-r--r--src/catch2/catch_message.cpp11
-rw-r--r--src/catch2/internal/catch_run_context.cpp7
-rw-r--r--tests/SelfTest/Baselines/automake.sw.approved.txt5
-rw-r--r--tests/SelfTest/Baselines/automake.sw.multi.approved.txt5
-rw-r--r--tests/SelfTest/Baselines/compact.sw.approved.txt14
-rw-r--r--tests/SelfTest/Baselines/compact.sw.multi.approved.txt14
-rw-r--r--tests/SelfTest/Baselines/console.std.approved.txt67
-rw-r--r--tests/SelfTest/Baselines/console.sw.approved.txt91
-rw-r--r--tests/SelfTest/Baselines/console.sw.multi.approved.txt91
-rw-r--r--tests/SelfTest/Baselines/console.swa4.approved.txt3
-rw-r--r--tests/SelfTest/Baselines/junit.sw.approved.txt51
-rw-r--r--tests/SelfTest/Baselines/junit.sw.multi.approved.txt51
-rw-r--r--tests/SelfTest/Baselines/sonarqube.sw.approved.txt49
-rw-r--r--tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt49
-rw-r--r--tests/SelfTest/Baselines/tap.sw.approved.txt20
-rw-r--r--tests/SelfTest/Baselines/tap.sw.multi.approved.txt20
-rw-r--r--tests/SelfTest/Baselines/teamcity.sw.approved.txt18
-rw-r--r--tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt18
-rw-r--r--tests/SelfTest/Baselines/xml.sw.approved.txt116
-rw-r--r--tests/SelfTest/Baselines/xml.sw.multi.approved.txt116
-rw-r--r--tests/SelfTest/UsageTests/Message.tests.cpp50
22 files changed, 830 insertions, 72 deletions
diff --git a/docs/logging.md b/docs/logging.md
index 79709386..1da97749 100644
--- a/docs/logging.md
+++ b/docs/logging.md
@@ -1,32 +1,30 @@
<a id="top"></a>
# Logging macros
-Additional messages can be logged during a test case. Note that the messages logged with `INFO` are scoped and thus will not be reported if failure occurs in scope preceding the message declaration. An example:
+Catch2 provides various macros for logging extra information when
+running a test. These macros default to being scoped, and associate with
+all assertions in the scope, regardless of whether they pass or fail.
+**example**
```cpp
-TEST_CASE("Foo") {
+TEST_CASE("Simple info") {
INFO("Test case start");
- for (int i = 0; i < 2; ++i) {
- INFO("The number is " << i);
- CHECK(i == 0);
+ SECTION("A") {
+ INFO("Section A");
+ CHECK(false); // 1
}
-}
-
-TEST_CASE("Bar") {
- INFO("Test case start");
- for (int i = 0; i < 2; ++i) {
- INFO("The number is " << i);
- CHECK(i == i);
+ SECTION("B") {
+ INFO("Section B");
+ CHECK(false); // 2
}
- CHECK(false);
+ CHECK(false); // 3
}
```
-When the `CHECK` fails in the "Foo" test case, then two messages will be printed.
-```
-Test case start
-The number is 1
-```
-When the last `CHECK` fails in the "Bar" test case, then only one message will be printed: `Test case start`.
+The first assertion will report messages "Test case start", and "Section A"
+as extra information. The second one will report messages "Test case
+started" and "Section B", while the third one will only report "Test case
+started" as the extra info.
+
## Logging without local scope
diff --git a/src/catch2/catch_message.cpp b/src/catch2/catch_message.cpp
index 7b09ab87..d3914a80 100644
--- a/src/catch2/catch_message.cpp
+++ b/src/catch2/catch_message.cpp
@@ -7,7 +7,6 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_message.hpp>
#include <catch2/interfaces/catch_interfaces_capture.hpp>
-#include <catch2/internal/catch_uncaught_exceptions.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
@@ -31,7 +30,7 @@ namespace Catch {
}
ScopedMessage::~ScopedMessage() {
- if ( !uncaught_exceptions() && !m_moved ){
+ if ( !m_moved ){
getResultCapture().popScopedMessage(m_info);
}
}
@@ -101,11 +100,9 @@ namespace Catch {
m_messages.back().message += " := ";
}
Capturer::~Capturer() {
- if ( !uncaught_exceptions() ){
- assert( m_captured == m_messages.size() );
- for( size_t i = 0; i < m_captured; ++i )
- m_resultCapture.popScopedMessage( m_messages[i] );
- }
+ assert( m_captured == m_messages.size() );
+ for ( size_t i = 0; i < m_captured; ++i )
+ m_resultCapture.popScopedMessage( m_messages[i] );
}
void Capturer::captureValue( size_t index, std::string const& value ) {
diff --git a/src/catch2/internal/catch_run_context.cpp b/src/catch2/internal/catch_run_context.cpp
index a6b99c02..6991ddcf 100644
--- a/src/catch2/internal/catch_run_context.cpp
+++ b/src/catch2/internal/catch_run_context.cpp
@@ -402,9 +402,6 @@ namespace Catch {
endInfo.durationInSeconds,
missingAssertions ) );
}
-
- m_messages.clear();
- m_messageScopes.clear();
}
void RunContext::sectionEndedEarly(SectionEndInfo&& endInfo) {
@@ -568,8 +565,10 @@ namespace Catch {
m_testCaseTracker->close();
handleUnfinishedSections();
- m_messages.clear();
m_messageScopes.clear();
+ // TBD: At this point, m_messages should be empty. Do we want to
+ // assert that this is true, or keep the defensive clear call?
+ m_messages.clear();
SectionStats testCaseSectionStats(CATCH_MOVE(testCaseSection), assertions, duration, missingAssertions);
m_reporter->sectionEnded(testCaseSectionStats);
diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt
index bff15522..c5f538ff 100644
--- a/tests/SelfTest/Baselines/automake.sw.approved.txt
+++ b/tests/SelfTest/Baselines/automake.sw.approved.txt
@@ -102,6 +102,8 @@ Nor would this
:test-result: PASS CAPTURE can deal with complex expressions involving commas
:test-result: PASS CAPTURE parses string and character constants
:test-result: PASS Capture and info messages
+:test-result: FAIL Captures do not leave block with an exception
+:test-result: FAIL Captures outlive section end
:test-result: PASS CaseInsensitiveEqualsTo is case insensitive
:test-result: PASS CaseInsensitiveLess is case insensitive
:test-result: PASS Character pretty printing
@@ -226,6 +228,9 @@ Nor would this
:test-result: PASS Scenario: Do that thing with the thing
:test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping
:test-result: PASS Scenario: Vector resizing affects size and capacity
+:test-result: FAIL Scoped message applies to all assertions in scope
+:test-result: FAIL Scoped messages do not leave block with an exception
+:test-result: FAIL Scoped messages outlive section end
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
index b30e5491..b573f81e 100644
--- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
@@ -100,6 +100,8 @@
:test-result: PASS CAPTURE can deal with complex expressions involving commas
:test-result: PASS CAPTURE parses string and character constants
:test-result: PASS Capture and info messages
+:test-result: FAIL Captures do not leave block with an exception
+:test-result: FAIL Captures outlive section end
:test-result: PASS CaseInsensitiveEqualsTo is case insensitive
:test-result: PASS CaseInsensitiveLess is case insensitive
:test-result: PASS Character pretty printing
@@ -224,6 +226,9 @@
:test-result: PASS Scenario: Do that thing with the thing
:test-result: PASS Scenario: This is a really long scenario name to see how the list command deals with wrapping
:test-result: PASS Scenario: Vector resizing affects size and capacity
+:test-result: FAIL Scoped message applies to all assertions in scope
+:test-result: FAIL Scoped messages do not leave block with an exception
+:test-result: FAIL Scoped messages outlive section end
:test-result: FAIL Sends stuff to stdout and stderr
:test-result: PASS Some simple comparisons between doubles
:test-result: FAIL Standard output from all sections is reported
diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt
index 5e2fef69..008d627c 100644
--- a/tests/SelfTest/Baselines/compact.sw.approved.txt
+++ b/tests/SelfTest/Baselines/compact.sw.approved.txt
@@ -85,7 +85,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smalle
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line}
-Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: {Unknown expression after the reported line} with 1 message: 'expected exception'
+Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line}
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
Compilation.tests.cpp:<line number>: passed: 42 == f for: 42 == {?}
@@ -363,6 +363,9 @@ Message.tests.cpp:<line number>: passed: with 7 messages: 'custom_index_op<int>{
Message.tests.cpp:<line number>: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: 'i := 2'
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: '3'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'a := 1'
+Message.tests.cpp:<line number>: passed: true with 1 message: 'a := 1'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'a := 1'
Details.tests.cpp:<line number>: passed: eq( "", "" ) for: true
Details.tests.cpp:<line number>: passed: !(eq( "", "a" )) for: !false
Details.tests.cpp:<line number>: passed: eq( "a", "a" ) for: true
@@ -1732,6 +1735,11 @@ BDD.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
BDD.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
BDD.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
BDD.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Message.tests.cpp:<line number>: failed: false with 1 message: 'This will be reported multiple times'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'This will be reported multiple times'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'Should be in scope at the end'
+Message.tests.cpp:<line number>: passed: true with 1 message: 'Should survive a section end'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'Should survive a section end'
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
@@ -2854,7 +2862,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
-test cases: 423 | 313 passed | 90 failed | 6 skipped | 14 failed as expected
-assertions: 2273 | 2087 passed | 151 failed | 35 failed as expected
+test cases: 428 | 313 passed | 95 failed | 6 skipped | 14 failed as expected
+assertions: 2281 | 2089 passed | 157 failed | 35 failed as expected
diff --git a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
index e96370e0..57303829 100644
--- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
@@ -83,7 +83,7 @@ Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smalle
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, WithinULP( -smallest_non_zero, 2 ) for: 0.0f is within 2 ULPs of -1.40129846e-45f ([-4.20389539e-45, 1.40129846e-45])
Matchers.tests.cpp:<line number>: passed: smallest_non_zero, !WithinULP( -smallest_non_zero, 1 ) for: 0.0f not is within 1 ULPs of -1.40129846e-45f ([-2.80259693e-45, -0.00000000e+00])
Generators.tests.cpp:<line number>: failed: unexpected exception with message: 'failure to init'; expression was: {Unknown expression after the reported line}
-Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: {Unknown expression after the reported line} with 1 message: 'expected exception'
+Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'expected exception'; expression was: {Unknown expression after the reported line}
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'
Compilation.tests.cpp:<line number>: passed: 42 == f for: 42 == {?}
@@ -361,6 +361,9 @@ Message.tests.cpp:<line number>: passed: with 7 messages: 'custom_index_op<int>{
Message.tests.cpp:<line number>: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: 'i := 2'
ToStringGeneral.tests.cpp:<line number>: passed: true with 1 message: '3'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'a := 1'
+Message.tests.cpp:<line number>: passed: true with 1 message: 'a := 1'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'a := 1'
Details.tests.cpp:<line number>: passed: eq( "", "" ) for: true
Details.tests.cpp:<line number>: passed: !(eq( "", "a" )) for: !false
Details.tests.cpp:<line number>: passed: eq( "a", "a" ) for: true
@@ -1730,6 +1733,11 @@ BDD.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
BDD.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
BDD.tests.cpp:<line number>: passed: v.capacity() >= 10 for: 10 >= 10
BDD.tests.cpp:<line number>: passed: v.size() == 0 for: 0 == 0
+Message.tests.cpp:<line number>: failed: false with 1 message: 'This will be reported multiple times'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'This will be reported multiple times'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'Should be in scope at the end'
+Message.tests.cpp:<line number>: passed: true with 1 message: 'Should survive a section end'
+Message.tests.cpp:<line number>: failed: false with 1 message: 'Should survive a section end'
Approx.tests.cpp:<line number>: passed: d == Approx( 1.23 ) for: 1.22999999999999998
==
Approx( 1.22999999999999998 )
@@ -2843,7 +2851,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
-test cases: 423 | 313 passed | 90 failed | 6 skipped | 14 failed as expected
-assertions: 2273 | 2087 passed | 151 failed | 35 failed as expected
+test cases: 428 | 313 passed | 95 failed | 6 skipped | 14 failed as expected
+assertions: 2281 | 2089 passed | 157 failed | 35 failed as expected
diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt
index b7933236..194b3676 100644
--- a/tests/SelfTest/Baselines/console.std.approved.txt
+++ b/tests/SelfTest/Baselines/console.std.approved.txt
@@ -47,8 +47,7 @@ Exception.tests.cpp:<line number>
Exception.tests.cpp:<line number>: FAILED:
{Unknown expression after the reported line}
-due to unexpected exception with messages:
- answer := 42
+due to unexpected exception with message:
expected exception
-------------------------------------------------------------------------------
@@ -349,6 +348,28 @@ due to unexpected exception with message:
unexpected exception
-------------------------------------------------------------------------------
+Captures do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
+Captures outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
Contains string matcher
-------------------------------------------------------------------------------
Matchers.tests.cpp:<line number>
@@ -988,6 +1009,44 @@ with expansion:
"this string contains 'abc' as a substring" matches "this string contains
'abc' as a" case sensitively
+-------------------------------------------------------------------------------
+Scoped message applies to all assertions in scope
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+-------------------------------------------------------------------------------
+Scoped messages do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should be in scope at the end
+
+-------------------------------------------------------------------------------
+Scoped messages outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should survive a section end
+
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
@@ -1613,6 +1672,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
-test cases: 423 | 331 passed | 71 failed | 7 skipped | 14 failed as expected
-assertions: 2252 | 2087 passed | 130 failed | 35 failed as expected
+test cases: 428 | 331 passed | 76 failed | 7 skipped | 14 failed as expected
+assertions: 2260 | 2089 passed | 136 failed | 35 failed as expected
diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt
index eb0ea034..1740933b 100644
--- a/tests/SelfTest/Baselines/console.sw.approved.txt
+++ b/tests/SelfTest/Baselines/console.sw.approved.txt
@@ -781,8 +781,7 @@ Exception.tests.cpp:<line number>
Exception.tests.cpp:<line number>: FAILED:
{Unknown expression after the reported line}
-due to unexpected exception with messages:
- answer := 42
+due to unexpected exception with message:
expected exception
-------------------------------------------------------------------------------
@@ -2868,6 +2867,40 @@ with message:
3
-------------------------------------------------------------------------------
+Captures do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
+Captures outlive section end
+ Dummy section
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+ CHECK( true )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
+Captures outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
CaseInsensitiveEqualsTo is case insensitive
Degenerate cases
-------------------------------------------------------------------------------
@@ -11026,6 +11059,56 @@ BDD.tests.cpp:<line number>: PASSED:
with expansion:
0 == 0
+-------------------------------------------------------------------------------
+Scoped message applies to all assertions in scope
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+-------------------------------------------------------------------------------
+Scoped messages do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should be in scope at the end
+
+-------------------------------------------------------------------------------
+Scoped messages outlive section end
+ Dummy section
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+ CHECK( true )
+with message:
+ Should survive a section end
+
+-------------------------------------------------------------------------------
+Scoped messages outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should survive a section end
+
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
@@ -19051,6 +19134,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
-test cases: 423 | 313 passed | 90 failed | 6 skipped | 14 failed as expected
-assertions: 2273 | 2087 passed | 151 failed | 35 failed as expected
+test cases: 428 | 313 passed | 95 failed | 6 skipped | 14 failed as expected
+assertions: 2281 | 2089 passed | 157 failed | 35 failed as expected
diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt
index 95f4f6f7..786ad4e9 100644
--- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt
@@ -779,8 +779,7 @@ Exception.tests.cpp:<line number>
Exception.tests.cpp:<line number>: FAILED:
{Unknown expression after the reported line}
-due to unexpected exception with messages:
- answer := 42
+due to unexpected exception with message:
expected exception
-------------------------------------------------------------------------------
@@ -2866,6 +2865,40 @@ with message:
3
-------------------------------------------------------------------------------
+Captures do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
+Captures outlive section end
+ Dummy section
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+ CHECK( true )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
+Captures outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ a := 1
+
+-------------------------------------------------------------------------------
CaseInsensitiveEqualsTo is case insensitive
Degenerate cases
-------------------------------------------------------------------------------
@@ -11025,6 +11058,56 @@ with expansion:
0 == 0
-------------------------------------------------------------------------------
+Scoped message applies to all assertions in scope
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+Message.tests.cpp:<line number>: FAILED:
+ CHECK( false )
+with message:
+ This will be reported multiple times
+
+-------------------------------------------------------------------------------
+Scoped messages do not leave block with an exception
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should be in scope at the end
+
+-------------------------------------------------------------------------------
+Scoped messages outlive section end
+ Dummy section
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: PASSED:
+ CHECK( true )
+with message:
+ Should survive a section end
+
+-------------------------------------------------------------------------------
+Scoped messages outlive section end
+-------------------------------------------------------------------------------
+Message.tests.cpp:<line number>
+...............................................................................
+
+Message.tests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ Should survive a section end
+
+-------------------------------------------------------------------------------
Sends stuff to stdout and stderr
-------------------------------------------------------------------------------
Misc.tests.cpp:<line number>
@@ -19040,6 +19123,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
-test cases: 423 | 313 passed | 90 failed | 6 skipped | 14 failed as expected
-assertions: 2273 | 2087 passed | 151 failed | 35 failed as expected
+test cases: 428 | 313 passed | 95 failed | 6 skipped | 14 failed as expected
+assertions: 2281 | 2089 passed | 157 failed | 35 failed as expected