2
0
mirror of https://github.com/catchorg/Catch2 synced 2026-01-19 04:52:08 +00:00

Add UNSCOPED_CAPTURE

Closes #2954
Closes #3010
This commit is contained in:
Martin Hořeňovský
2026-01-08 14:35:05 +01:00
parent b59f4f3522
commit 2580eadc42
26 changed files with 265 additions and 54 deletions

View File

@@ -29,7 +29,7 @@ with the same name.
## Prefixing Catch macros
CATCH_CONFIG_PREFIX_ALL // Prefix all macros with CATCH_
CATCH_CONFIG_PREFIX_MESSAGES // Prefix only INFO, UNSCOPED_INFO, WARN and CAPTURE
CATCH_CONFIG_PREFIX_MESSAGES // Prefix only message macros ((UNSCOPED_)INFO, WARN, (UNSCOPED_)CAPTURE)
To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```).

View File

@@ -26,19 +26,22 @@ started" and "Section B", while the third one will only report "Test case
started" as the extra info.
## Logging without local scope
## Logging outside of current scope
> [Introduced](https://github.com/catchorg/Catch2/issues/1522) in Catch2 2.7.0.
> `UNSCOPED_INFO` was [introduced](https://github.com/catchorg/Catch2/issues/1522) in Catch2 2.7.0.
`UNSCOPED_INFO` is similar to `INFO` with two key differences:
> `UNSCOPED_CAPTURE` was introduced in Catch2 X.Y.Z.
- Lifetime of an unscoped message is not tied to its own scope.
The `UNSCOPED_X` macros are similar to their plain `X` macro counterparts,
with two key differences:
- The lifetime of an unscoped message is not tied to its own scope.
- An unscoped message can be reported by the first following assertion only, regardless of the result of that assertion.
In other words, lifetime of `UNSCOPED_INFO` is limited by the following assertion (or by the end of test case/section, whichever comes first) whereas lifetime of `INFO` is limited by its own scope.
These differences make this macro useful for reporting information from helper functions or inner scopes. An example:
In other words, the `UNSCOPED_X` macros are useful to add extra information
to the next assertion, e.g. from helper functions or inner scopes.
An example:
```cpp
void print_some_info() {
UNSCOPED_INFO("Info from helper");
@@ -83,9 +86,16 @@ Second info
Second unscoped info
```
Note that unscoped messages are not passed between test cases, even if
there were no assertions between them.
## Streaming macros
All these macros allow heterogeneous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it.
Apart from `CAPTURE` (and its close sibling, `UNSCOPED_CAPTURE`), message
macros support gradual streaming of messages and values in the same way
that the standard streams do.
E.g.:
```c++
@@ -99,9 +109,6 @@ These macros come in three forms:
The message is logged to a buffer, but only reported with next assertions that are logged. This allows you to log contextual information in case of failures which is not shown during a successful test run (for the console reporter, without -s). Messages are removed from the buffer at the end of their scope, so may be used, for example, in loops.
_Note that in Catch2 2.x.x `INFO` can be used without a trailing semicolon as there is a trailing semicolon inside macro.
This semicolon will be removed with next major version. It is highly advised to use a trailing semicolon after `INFO` macro._
**UNSCOPED_INFO(** _message expression_ **)**
> [Introduced](https://github.com/catchorg/Catch2/issues/1522) in Catch2 2.7.0.
@@ -128,6 +135,10 @@ AS `FAIL`, but does not abort the test
**CAPTURE(** _expression1_, _expression2_, ... **)**
**UNSCOPED_CAPTURE(** _expression1_, _expression2_, ... **)**
> `UNSCOPED_CAPTURE` was introduced in Catch2 X.Y.Z.
Sometimes you just want to log a value of variable, or expression. For
convenience, we provide the `CAPTURE` macro, that can take a variable,
or an expression, and prints out that variable/expression and its value

View File

@@ -38,7 +38,9 @@ namespace Catch {
Capturer::Capturer( StringRef macroName,
SourceLineInfo const& lineInfo,
ResultWas::OfType resultType,
StringRef names ) {
StringRef names,
bool isScoped):
m_isScoped(isScoped) {
auto trimmed = [&] (size_t start, size_t end) {
while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
++start;
@@ -99,15 +101,21 @@ namespace Catch {
}
Capturer::~Capturer() {
assert( m_captured == m_messages.size() );
for (auto const& message : m_messages) {
IResultCapture::popScopedMessage( message.sequence );
if ( m_isScoped ) {
for ( auto const& message : m_messages ) {
IResultCapture::popScopedMessage( message.sequence );
}
}
}
void Capturer::captureValue( size_t index, std::string const& value ) {
assert( index < m_messages.size() );
m_messages[index].message += value;
IResultCapture::pushScopedMessage( CATCH_MOVE( m_messages[index] ) );
if ( m_isScoped ) {
IResultCapture::pushScopedMessage( CATCH_MOVE( m_messages[index] ) );
} else {
IResultCapture::addUnscopedMessage( CATCH_MOVE( m_messages[index] ) );
}
m_captured++;
}

View File

@@ -64,8 +64,9 @@ namespace Catch {
class Capturer {
std::vector<MessageInfo> m_messages;
size_t m_captured = 0;
bool m_isScoped = false;
public:
Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names, bool isScoped );
Capturer(Capturer const&) = delete;
Capturer& operator=(Capturer const&) = delete;
@@ -97,11 +98,12 @@ namespace Catch {
} while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
Catch::Capturer varName( macroName##_catch_sr, \
CATCH_INTERNAL_LINEINFO, \
Catch::ResultWas::Info, \
#__VA_ARGS__##_catch_sr ); \
#define INTERNAL_CATCH_CAPTURE( varName, macroName, scopedCapture, ... ) \
Catch::Capturer varName( macroName##_catch_sr, \
CATCH_INTERNAL_LINEINFO, \
Catch::ResultWas::Info, \
#__VA_ARGS__##_catch_sr, \
scopedCapture ); \
varName.captureValues( 0, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
@@ -118,28 +120,32 @@ namespace Catch {
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( "CATCH_UNSCOPED_INFO", msg )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", __VA_ARGS__ )
#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE", true, __VA_ARGS__ )
#define CATCH_UNSCOPED_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_UNSCOPED_CAPTURE", false, __VA_ARGS__ )
#elif defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
#define CATCH_INFO( msg ) (void)(0)
#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
#define CATCH_WARN( msg ) (void)(0)
#define CATCH_CAPTURE( ... ) (void)(0)
#define CATCH_INFO( msg ) (void)(0)
#define CATCH_UNSCOPED_INFO( msg ) (void)(0)
#define CATCH_WARN( msg ) (void)(0)
#define CATCH_CAPTURE( ... ) (void)(0)
#define CATCH_UNSCOPED_CAPTURE( ... ) (void)(0)
#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && !defined(CATCH_CONFIG_DISABLE)
#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 CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", __VA_ARGS__ )
#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE", true, __VA_ARGS__ )
#define UNSCOPED_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "UNSCOPED_CAPTURE", false, __VA_ARGS__ )
#elif !defined(CATCH_CONFIG_PREFIX_MESSAGES) && defined(CATCH_CONFIG_DISABLE)
#define INFO( msg ) (void)(0)
#define UNSCOPED_INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
#define CAPTURE( ... ) (void)(0)
#define INFO( msg ) (void)(0)
#define UNSCOPED_INFO( msg ) (void)(0)
#define WARN( msg ) (void)(0)
#define CAPTURE( ... ) (void)(0)
#define UNSCOPED_CAPTURE( ... ) (void)(0)
#endif // end of user facing macro declarations

View File

@@ -65,6 +65,7 @@ namespace Catch {
static void pushScopedMessage( MessageInfo&& message );
static void popScopedMessage( unsigned int messageId );
static void addUnscopedMessage( MessageInfo&& message );
static void emplaceUnscopedMessage( MessageBuilder&& builder );
virtual void handleFatalErrorCondition( StringRef message ) = 0;

View File

@@ -211,15 +211,18 @@ namespace Catch {
// we only keep around the raw msg ids.
~MessageHolder() = default;
void addUnscopedMessage(MessageBuilder&& builder) {
void addUnscopedMessage( MessageInfo&& info ) {
repairUnscopedMessageInvariant();
MessageInfo info( CATCH_MOVE( builder.m_info ) );
info.message = builder.m_stream.str();
unscoped_ids.push_back( info.sequence );
messages.push_back( CATCH_MOVE( info ) );
}
void addUnscopedMessage(MessageBuilder&& builder) {
MessageInfo info( CATCH_MOVE( builder.m_info ) );
info.message = builder.m_stream.str();
addUnscopedMessage( CATCH_MOVE( info ) );
}
void addScopedMessage(MessageInfo&& info) {
messages.push_back( CATCH_MOVE( info ) );
}
@@ -894,6 +897,10 @@ namespace Catch {
Detail::g_messageHolder().addUnscopedMessage( CATCH_MOVE( builder ) );
}
void IResultCapture::addUnscopedMessage( MessageInfo&& message ) {
Detail::g_messageHolder().addUnscopedMessage( CATCH_MOVE( message ) );
}
void seedRng(IConfig const& config) {
sharedRng().seed(config.rngSeed());
}

View File

@@ -67,6 +67,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
int i = 1;
CATCH_CAPTURE( i );
CATCH_CAPTURE( i, i + 1 );
CATCH_UNSCOPED_CAPTURE( i + 2, i + 3 );
CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
CATCH_FAIL_CHECK( "failure" );
}

View File

@@ -48,6 +48,7 @@ TEST_CASE( "Disabled Macros" ) {
CAPTURE( 1 );
CAPTURE( 1, "captured" );
UNSCOPED_CAPTURE( 3 );
REQUIRE_THAT( 1,
Catch::Matchers::Predicate( []( int ) { return false; } ) );
@@ -68,6 +69,7 @@ TEST_CASE_PERSISTENT_FIXTURE( DisabledFixture, "Disabled Persistent Fixture" ) {
CAPTURE( 1 );
CAPTURE( 1, "captured" );
UNSCOPED_CAPTURE( 3 );
REQUIRE_THAT( 1,
Catch::Matchers::Predicate( []( int ) { return false; } ) );

View File

@@ -299,6 +299,7 @@ Message from section two
:test-result: PASS Trim strings
:test-result: PASS Type conversions of RangeEquals and similar
:test-result: FAIL Unexpected exceptions can be translated
:test-result: FAIL Unscoped capture outlives scope
:test-result: PASS Upcasting special member functions
:test-result: PASS Usage of AllMatch range matcher
:test-result: PASS Usage of AllTrue range matcher

View File

@@ -292,6 +292,7 @@
:test-result: PASS Trim strings
:test-result: PASS Type conversions of RangeEquals and similar
:test-result: FAIL Unexpected exceptions can be translated
:test-result: FAIL Unscoped capture outlives scope
:test-result: PASS Upcasting special member functions
:test-result: PASS Usage of AllMatch range matcher
:test-result: PASS Usage of AllTrue range matcher

View File

@@ -2205,6 +2205,7 @@ MatchersRanges.tests.cpp:<line number>: passed: a, UnorderedRangeEquals( b ) for
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14000000000000012'
Message.tests.cpp:<line number>: failed: false with 3 messages: 'i := 1' and 'j := 2' and 'i + j := 3'
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
MatchersRanges.tests.cpp:<line number>: passed: data, AllMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match has size == 5
@@ -2894,7 +2895,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: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected
assertions: 2309 | 2110 passed | 157 failed | 42 failed as expected
test cases: 437 | 317 passed | 96 failed | 6 skipped | 18 failed as expected
assertions: 2311 | 2110 passed | 158 failed | 43 failed as expected

View File

@@ -2198,6 +2198,7 @@ MatchersRanges.tests.cpp:<line number>: passed: a, UnorderedRangeEquals( b ) for
MatchersRanges.tests.cpp:<line number>: passed: vector_a, RangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } elements are { 2, 3, 4 }
MatchersRanges.tests.cpp:<line number>: passed: vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
Exception.tests.cpp:<line number>: failed: unexpected exception with message: '3.14000000000000012'
Message.tests.cpp:<line number>: failed: false with 3 messages: 'i := 1' and 'j := 2' and 'i + j := 3'
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
UniquePtr.tests.cpp:<line number>: passed: bptr->i == 3 for: 3 == 3
MatchersRanges.tests.cpp:<line number>: passed: data, AllMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match has size == 5
@@ -2883,7 +2884,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: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected
assertions: 2309 | 2110 passed | 157 failed | 42 failed as expected
test cases: 437 | 317 passed | 96 failed | 6 skipped | 18 failed as expected
assertions: 2311 | 2110 passed | 158 failed | 43 failed as expected

View File

@@ -1203,6 +1203,19 @@ Exception.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
3.14000000000000012
-------------------------------------------------------------------------------
Unscoped capture outlives scope
-------------------------------------------------------------------------------
Message.tests.cpp:<line number>
...............................................................................
Message.tests.cpp:<line number>: FAILED:
REQUIRE( false )
with messages:
i := 1
j := 2
i + j := 3
-------------------------------------------------------------------------------
Vector Approx matcher -- failing
Empty and non empty vectors are not approx equal
@@ -1730,6 +1743,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 436 | 335 passed | 76 failed | 7 skipped | 18 failed as expected
assertions: 2288 | 2110 passed | 136 failed | 42 failed as expected
test cases: 437 | 335 passed | 76 failed | 7 skipped | 19 failed as expected
assertions: 2289 | 2110 passed | 136 failed | 43 failed as expected

View File

@@ -14324,6 +14324,29 @@ Exception.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
3.14000000000000012
-------------------------------------------------------------------------------
Unscoped capture outlives scope
A
-------------------------------------------------------------------------------
Message.tests.cpp:<line number>
...............................................................................
No assertions in section 'A'
-------------------------------------------------------------------------------
Unscoped capture outlives scope
-------------------------------------------------------------------------------
Message.tests.cpp:<line number>
...............................................................................
Message.tests.cpp:<line number>: FAILED:
REQUIRE( false )
with messages:
i := 1
j := 2
i + j := 3
-------------------------------------------------------------------------------
Upcasting special member functions
Move constructor
@@ -19349,6 +19372,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected
assertions: 2309 | 2110 passed | 157 failed | 42 failed as expected
test cases: 437 | 317 passed | 96 failed | 6 skipped | 18 failed as expected
assertions: 2311 | 2110 passed | 158 failed | 43 failed as expected

View File

@@ -14317,6 +14317,29 @@ Exception.tests.cpp:<line number>: FAILED:
due to unexpected exception with message:
3.14000000000000012
-------------------------------------------------------------------------------
Unscoped capture outlives scope
A
-------------------------------------------------------------------------------
Message.tests.cpp:<line number>
...............................................................................
No assertions in section 'A'
-------------------------------------------------------------------------------
Unscoped capture outlives scope
-------------------------------------------------------------------------------
Message.tests.cpp:<line number>
...............................................................................
Message.tests.cpp:<line number>: FAILED:
REQUIRE( false )
with messages:
i := 1
j := 2
i + j := 3
-------------------------------------------------------------------------------
Upcasting special member functions
Move constructor
@@ -19338,6 +19361,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 436 | 317 passed | 95 failed | 6 skipped | 18 failed as expected
assertions: 2309 | 2110 passed | 157 failed | 42 failed as expected
test cases: 437 | 317 passed | 96 failed | 6 skipped | 18 failed as expected
assertions: 2311 | 2110 passed | 158 failed | 43 failed as expected

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2321" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="141" skipped="12" tests="2323" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -1694,6 +1694,18 @@ FAILED:
at Exception.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="Unscoped capture outlives scope" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/>
<failure message="false" type="REQUIRE">
FAILED:
REQUIRE( false )
i := 1
j := 2
i + j := 3
at Message.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.global" name="Unscoped capture outlives scope/A" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/Move constructor" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/move assignment" time="{duration}" status="run"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2321" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="141" skipped="12" tests="2323" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -1693,6 +1693,18 @@ FAILED:
at Exception.tests.cpp:<line number>
</error>
</testcase>
<testcase classname="<exe-name>.global" name="Unscoped capture outlives scope" time="{duration}" status="run">
<skipped message="TEST_CASE tagged with !mayfail"/>
<failure message="false" type="REQUIRE">
FAILED:
REQUIRE( false )
i := 1
j := 2
i + j := 3
at Message.tests.cpp:<line number>
</failure>
</testcase>
<testcase classname="<exe-name>.global" name="Unscoped capture outlives scope/A" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/Move constructor" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Upcasting special member functions/move assignment" time="{duration}" status="run"/>

View File

@@ -1833,6 +1833,17 @@ at Message.tests.cpp:<line number>
<testCase name="Standard output from all sections is reported/one" duration="{duration}"/>
<testCase name="Standard output from all sections is reported/two" duration="{duration}"/>
<testCase name="The NO_FAIL macro reports a failure but does not fail the test" duration="{duration}"/>
<testCase name="Unscoped capture outlives scope" duration="{duration}">
<skipped message="REQUIRE(false)">
FAILED:
REQUIRE( false )
i := 1
j := 2
i + j := 3
at Message.tests.cpp:<line number>
</skipped>
</testCase>
<testCase name="Unscoped capture outlives scope/A" duration="{duration}"/>
<testCase name="just failure" duration="{duration}">
<failure message="FAIL()">
FAILED:

View File

@@ -1832,6 +1832,17 @@ at Message.tests.cpp:<line number>
<testCase name="Standard output from all sections is reported/one" duration="{duration}"/>
<testCase name="Standard output from all sections is reported/two" duration="{duration}"/>
<testCase name="The NO_FAIL macro reports a failure but does not fail the test" duration="{duration}"/>
<testCase name="Unscoped capture outlives scope" duration="{duration}">
<skipped message="REQUIRE(false)">
FAILED:
REQUIRE( false )
i := 1
j := 2
i + j := 3
at Message.tests.cpp:<line number>
</skipped>
</testCase>
<testCase name="Unscoped capture outlives scope/A" duration="{duration}"/>
<testCase name="just failure" duration="{duration}">
<failure message="FAIL()">
FAILED:

View File

@@ -3417,6 +3417,8 @@ ok {test-number} - vector_a, RangeEquals( array_a_plus_1, close_enough ) for: {
ok {test-number} - vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
# Unexpected exceptions can be translated
not ok {test-number} - unexpected exception with message: '3.14000000000000012'
# Unscoped capture outlives scope
not ok {test-number} - false with 3 messages: 'i := 1' and 'j := 2' and 'i + j := 3'
# Upcasting special member functions
ok {test-number} - bptr->i == 3 for: 3 == 3
# Upcasting special member functions
@@ -4639,5 +4641,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2321
1..2323

View File

@@ -3410,6 +3410,8 @@ ok {test-number} - vector_a, RangeEquals( array_a_plus_1, close_enough ) for: {
ok {test-number} - vector_a, UnorderedRangeEquals( array_a_plus_1, close_enough ) for: { 1, 2, 3 } unordered elements are { 2, 3, 4 }
# Unexpected exceptions can be translated
not ok {test-number} - unexpected exception with message: '3.14000000000000012'
# Unscoped capture outlives scope
not ok {test-number} - false with 3 messages: 'i := 1' and 'j := 2' and 'i + j := 3'
# Upcasting special member functions
ok {test-number} - bptr->i == 3 for: 3 == 3
# Upcasting special member functions
@@ -4628,5 +4630,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2321
1..2323

View File

@@ -727,6 +727,9 @@
##teamcity[testStarted name='Unexpected exceptions can be translated']
##teamcity[testFailed name='Unexpected exceptions can be translated' message='Exception.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with message:|n "3.14000000000000012"']
##teamcity[testFinished name='Unexpected exceptions can be translated' duration="{duration}"]
##teamcity[testStarted name='Unscoped capture outlives scope']
##teamcity[testIgnored name='Unscoped capture outlives scope' message='Message.tests.cpp:<line number>|n...............................................................................|n|nMessage.tests.cpp:<line number>|nexpression failed with messages:|n "i := 1"|n "j := 2"|n "i + j := 3"|n REQUIRE( false )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testFinished name='Unscoped capture outlives scope' duration="{duration}"]
##teamcity[testStarted name='Upcasting special member functions']
##teamcity[testFinished name='Upcasting special member functions' duration="{duration}"]
##teamcity[testStarted name='Usage of AllMatch range matcher']

View File

@@ -727,6 +727,9 @@
##teamcity[testStarted name='Unexpected exceptions can be translated']
##teamcity[testFailed name='Unexpected exceptions can be translated' message='Exception.tests.cpp:<line number>|n...............................................................................|n|nException.tests.cpp:<line number>|nunexpected exception with message:|n "3.14000000000000012"']
##teamcity[testFinished name='Unexpected exceptions can be translated' duration="{duration}"]
##teamcity[testStarted name='Unscoped capture outlives scope']
##teamcity[testIgnored name='Unscoped capture outlives scope' message='Message.tests.cpp:<line number>|n...............................................................................|n|nMessage.tests.cpp:<line number>|nexpression failed with messages:|n "i := 1"|n "j := 2"|n "i + j := 3"|n REQUIRE( false )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n']
##teamcity[testFinished name='Unscoped capture outlives scope' duration="{duration}"]
##teamcity[testStarted name='Upcasting special member functions']
##teamcity[testFinished name='Upcasting special member functions' duration="{duration}"]
##teamcity[testStarted name='Usage of AllMatch range matcher']

View File

@@ -16561,6 +16561,29 @@ There is no extra whitespace here
</Exception>
<OverallResult success="false" skips="0"/>
</TestCase>
<TestCase name="Unscoped capture outlives scope" tags="[!shouldfail][capture][messages][unscoped]" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<Section name="A" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<OverallResults successes="0" failures="1" expectedFailures="0" skipped="false"/>
</Section>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
i := 1
</Info>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
j := 2
</Info>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
i + j := 3
</Info>
<Expression success="false" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<Original>
false
</Original>
<Expanded>
false
</Expanded>
</Expression>
<OverallResult success="false" skips="0"/>
</TestCase>
<TestCase name="Upcasting special member functions" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Move constructor" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
@@ -22393,6 +22416,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2110" failures="157" expectedFailures="42" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="18" skips="6"/>
<OverallResults successes="2110" failures="158" expectedFailures="43" skips="12"/>
<OverallResultsCases successes="317" failures="96" expectedFailures="18" skips="6"/>
</Catch2TestRun>

View File

@@ -16561,6 +16561,29 @@ There is no extra whitespace here
</Exception>
<OverallResult success="false" skips="0"/>
</TestCase>
<TestCase name="Unscoped capture outlives scope" tags="[!shouldfail][capture][messages][unscoped]" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<Section name="A" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<OverallResults successes="0" failures="1" expectedFailures="0" skipped="false"/>
</Section>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
i := 1
</Info>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
j := 2
</Info>
<Info filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
i + j := 3
</Info>
<Expression success="false" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Message.tests.cpp" >
<Original>
false
</Original>
<Expanded>
false
</Expanded>
</Expression>
<OverallResult success="false" skips="0"/>
</TestCase>
<TestCase name="Upcasting special member functions" tags="[internals][unique-ptr]" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Section name="Move constructor" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/UniquePtr.tests.cpp" >
@@ -22392,6 +22415,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2110" failures="157" expectedFailures="42" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="18" skips="6"/>
<OverallResults successes="2110" failures="158" expectedFailures="43" skips="12"/>
<OverallResultsCases successes="317" failures="96" expectedFailures="18" skips="6"/>
</Catch2TestRun>

View File

@@ -369,3 +369,13 @@ TEST_CASE(
UNSCOPED_INFO( "b" );
REQUIRE( false );
}
TEST_CASE( "Unscoped capture outlives scope",
"[messages][unscoped][capture][!shouldfail]" ) {
int i = 1;
SECTION( "A" ) {
int j = 2;
UNSCOPED_CAPTURE( i, j, i + j );
}
REQUIRE( false );
}