mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
v3.2.0
This commit is contained in:
parent
c276b530ee
commit
65cc7fd2ae
@ -31,7 +31,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(Catch2
|
project(Catch2
|
||||||
VERSION 3.1.1 # CML version placeholder, don't delete
|
VERSION 3.2.0 # CML version placeholder, don't delete
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||||
# we do not target yet.
|
# we do not target yet.
|
||||||
|
@ -69,7 +69,7 @@ test execution. Specifically it understands
|
|||||||
|
|
||||||
> Support for `XML_OUTPUT_FILE` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1
|
> Support for `XML_OUTPUT_FILE` was [introduced](https://github.com/catchorg/Catch2/pull/2399) in Catch2 3.0.1
|
||||||
|
|
||||||
> Support for `TESTBRIDGE_TEST_ONLY` and sharding was introduced in Catch2 X.Y.Z
|
> Support for `TESTBRIDGE_TEST_ONLY` and sharding was introduced in Catch2 3.2.0
|
||||||
|
|
||||||
This integration is enabled via either a [compile time configuration
|
This integration is enabled via either a [compile time configuration
|
||||||
option](configuration.md#bazel-support), or via `BAZEL_TEST` environment
|
option](configuration.md#bazel-support), or via `BAZEL_TEST` environment
|
||||||
|
@ -159,7 +159,7 @@ by using `_NO_` in the macro, e.g. `CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS`.
|
|||||||
|
|
||||||
> [`CATCH_CONFIG_ANDROID_LOGWRITE`](https://github.com/catchorg/Catch2/issues/1743) and [`CATCH_CONFIG_GLOBAL_NEXTAFTER`](https://github.com/catchorg/Catch2/pull/1739) were introduced in Catch2 2.10.0
|
> [`CATCH_CONFIG_ANDROID_LOGWRITE`](https://github.com/catchorg/Catch2/issues/1743) and [`CATCH_CONFIG_GLOBAL_NEXTAFTER`](https://github.com/catchorg/Catch2/pull/1739) were introduced in Catch2 2.10.0
|
||||||
|
|
||||||
> `CATCH_CONFIG_GETENV` was [introduced](https://github.com/catchorg/Catch2/pull/2562) in Catch2 X.Y.Z
|
> `CATCH_CONFIG_GETENV` was [introduced](https://github.com/catchorg/Catch2/pull/2562) in Catch2 3.2.0
|
||||||
|
|
||||||
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
Currently Catch enables `CATCH_CONFIG_WINDOWS_SEH` only when compiled with MSVC, because some versions of MinGW do not have the necessary Win32 API support.
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# Release notes
|
# Release notes
|
||||||
**Contents**<br>
|
**Contents**<br>
|
||||||
|
[3.2.0](#320)<br>
|
||||||
[3.1.1](#311)<br>
|
[3.1.1](#311)<br>
|
||||||
[3.1.0](#310)<br>
|
[3.1.0](#310)<br>
|
||||||
[3.0.1](#301)<br>
|
[3.0.1](#301)<br>
|
||||||
@ -52,6 +53,42 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3.2.0
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
* Catch2 now compiles on PlayStation (#2562)
|
||||||
|
* Added `CATCH_CONFIG_GETENV` compile-time toggle (#2562)
|
||||||
|
* This toggle guards whether Catch2 calls `std::getenv` when reading env variables
|
||||||
|
* Added support for more Bazel test environment variables
|
||||||
|
* `TESTBRIDGE_TEST_ONLY` is now supported (#2490)
|
||||||
|
* Sharding variables, `TEST_SHARD_INDEX`, `TEST_TOTAL_SHARDS`, `TEST_SHARD_STATUS_FILE`, are now all supported (#2491)
|
||||||
|
* Bunch of small tweaks and improvements in reporters
|
||||||
|
* The TAP and SonarQube reporters output the used test filters
|
||||||
|
* The XML reporter now also reports the version of its output format
|
||||||
|
* The compact reporter now uses the same summary output as the console reporter (#878, #2554)
|
||||||
|
* Added support for asserting on types that can only be compared with literal 0 (#2555)
|
||||||
|
* A canonical example is C++20's `std::*_ordering` types, which cannot be compared with an `int` variable, only `0`
|
||||||
|
* The support extends to any type with this property, not just the ones in stdlib
|
||||||
|
* This change imposes 2-3% slowdown on compiling files that are heavy on `REQUIRE` and friends
|
||||||
|
* **This required significant rewrite of decomposition, there might be bugs**
|
||||||
|
* Simplified internals of matcher related macros
|
||||||
|
* This provides about ~2% speed up compiling files that are heavy on `REQUIRE_THAT` and friends
|
||||||
|
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Cleaned out some warnings and static analysis issues
|
||||||
|
* Suppressed `-Wcomma` warning rarely occuring in templated test cases (#2543)
|
||||||
|
* Constified implementation details in `INFO` (#2564)
|
||||||
|
* Made `MatcherGenericBase` copy constructor const (#2566)
|
||||||
|
* Fixed serialization of test filters so the output roundtrips
|
||||||
|
* This means that e.g. `./tests/SelfTest "aaa bbb", [approx]` outputs `Filters: "aaa bbb",[approx]`
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous
|
||||||
|
* Catch2's build no longer leaks `-ffile-prefix-map` setting to dependees (#2533)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 3.1.1
|
## 3.1.1
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
// Catch v3.1.1
|
// Catch v3.2.0
|
||||||
// Generated: 2022-10-17 18:47:22.400176
|
// Generated: 2022-11-16 19:30:16.114602
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
// This file is an amalgamation of multiple different files.
|
// This file is an amalgamation of multiple different files.
|
||||||
// You probably shouldn't edit it directly.
|
// You probably shouldn't edit it directly.
|
||||||
@ -508,33 +508,74 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
#include <fstream>
|
||||||
bool provideBazelReporterOutput() {
|
|
||||||
#if defined(CATCH_CONFIG_BAZEL_SUPPORT)
|
|
||||||
return true;
|
|
||||||
#elif defined(CATCH_PLATFORM_WINDOWS_UWP)
|
|
||||||
// UWP does not support environment variables
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
|
|
||||||
# if defined( _MSC_VER )
|
|
||||||
// On Windows getenv throws a warning as there is no input validation,
|
|
||||||
// since the switch is hardcoded, this should not be an issue.
|
|
||||||
# pragma warning( push )
|
|
||||||
# pragma warning( disable : 4996 )
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return std::getenv( "BAZEL_TEST" ) != nullptr;
|
|
||||||
|
|
||||||
# if defined( _MSC_VER )
|
|
||||||
# pragma warning( pop )
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static bool enableBazelEnvSupport() {
|
||||||
|
#if defined( CATCH_CONFIG_BAZEL_SUPPORT )
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return Detail::getEnv( "BAZEL_TEST" ) != nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bazelShardingOptions {
|
||||||
|
unsigned int shardIndex, shardCount;
|
||||||
|
std::string shardFilePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Optional<bazelShardingOptions> readBazelShardingOptions() {
|
||||||
|
const auto bazelShardIndex = Detail::getEnv( "TEST_SHARD_INDEX" );
|
||||||
|
const auto bazelShardTotal = Detail::getEnv( "TEST_TOTAL_SHARDS" );
|
||||||
|
const auto bazelShardInfoFile = Detail::getEnv( "TEST_SHARD_STATUS_FILE" );
|
||||||
|
|
||||||
|
|
||||||
|
const bool has_all =
|
||||||
|
bazelShardIndex && bazelShardTotal && bazelShardInfoFile;
|
||||||
|
if ( !has_all ) {
|
||||||
|
// We provide nice warning message if the input is
|
||||||
|
// misconfigured.
|
||||||
|
auto warn = []( const char* env_var ) {
|
||||||
|
Catch::cerr()
|
||||||
|
<< "Warning: Bazel shard configuration is missing '"
|
||||||
|
<< env_var << "'. Shard configuration is skipped.\n";
|
||||||
|
};
|
||||||
|
if ( !bazelShardIndex ) {
|
||||||
|
warn( "TEST_SHARD_INDEX" );
|
||||||
|
}
|
||||||
|
if ( !bazelShardTotal ) {
|
||||||
|
warn( "TEST_TOTAL_SHARDS" );
|
||||||
|
}
|
||||||
|
if ( !bazelShardInfoFile ) {
|
||||||
|
warn( "TEST_SHARD_STATUS_FILE" );
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto shardIndex = parseUInt( bazelShardIndex );
|
||||||
|
if ( !shardIndex ) {
|
||||||
|
Catch::cerr()
|
||||||
|
<< "Warning: could not parse 'TEST_SHARD_INDEX' ('" << bazelShardIndex
|
||||||
|
<< "') as unsigned int.\n";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto shardTotal = parseUInt( bazelShardTotal );
|
||||||
|
if ( !shardTotal ) {
|
||||||
|
Catch::cerr()
|
||||||
|
<< "Warning: could not parse 'TEST_TOTAL_SHARD' ('"
|
||||||
|
<< bazelShardTotal << "') as unsigned int.\n";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return bazelShardingOptions{
|
||||||
|
*shardIndex, *shardTotal, bazelShardInfoFile };
|
||||||
|
|
||||||
|
}
|
||||||
|
} // end namespace
|
||||||
|
|
||||||
|
|
||||||
bool operator==( ProcessedReporterSpec const& lhs,
|
bool operator==( ProcessedReporterSpec const& lhs,
|
||||||
ProcessedReporterSpec const& rhs ) {
|
ProcessedReporterSpec const& rhs ) {
|
||||||
return lhs.name == rhs.name &&
|
return lhs.name == rhs.name &&
|
||||||
@ -556,17 +597,6 @@ namespace Catch {
|
|||||||
elem = trim(elem);
|
elem = trim(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TestSpecParser parser(ITagAliasRegistry::get());
|
|
||||||
if (!m_data.testsOrTags.empty()) {
|
|
||||||
m_hasTestFilters = true;
|
|
||||||
for (auto const& testOrTags : m_data.testsOrTags) {
|
|
||||||
parser.parse(testOrTags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_testSpec = parser.testSpec();
|
|
||||||
|
|
||||||
|
|
||||||
// Insert the default reporter if user hasn't asked for a specfic one
|
// Insert the default reporter if user hasn't asked for a specfic one
|
||||||
if ( m_data.reporterSpecifications.empty() ) {
|
if ( m_data.reporterSpecifications.empty() ) {
|
||||||
m_data.reporterSpecifications.push_back( {
|
m_data.reporterSpecifications.push_back( {
|
||||||
@ -579,29 +609,21 @@ namespace Catch {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CATCH_PLATFORM_WINDOWS_UWP)
|
if ( enableBazelEnvSupport() ) {
|
||||||
if(provideBazelReporterOutput()){
|
readBazelEnvVars();
|
||||||
// Register a JUnit reporter for Bazel. Bazel sets an environment
|
}
|
||||||
// variable with the path to XML output. If this file is written to
|
|
||||||
// during test, Bazel will not generate a default XML output.
|
// Bazel support can modify the test specs, so parsing has to happen
|
||||||
// This allows the XML output file to contain higher level of detail
|
// after reading Bazel env vars.
|
||||||
// than what is possible otherwise.
|
TestSpecParser parser( ITagAliasRegistry::get() );
|
||||||
# if defined( _MSC_VER )
|
if ( !m_data.testsOrTags.empty() ) {
|
||||||
// On Windows getenv throws a warning as there is no input validation,
|
m_hasTestFilters = true;
|
||||||
// since the key is hardcoded, this should not be an issue.
|
for ( auto const& testOrTags : m_data.testsOrTags ) {
|
||||||
# pragma warning( push )
|
parser.parse( testOrTags );
|
||||||
# pragma warning( disable : 4996 )
|
|
||||||
# endif
|
|
||||||
const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" );
|
|
||||||
# if defined( _MSC_VER )
|
|
||||||
# pragma warning( pop )
|
|
||||||
# endif
|
|
||||||
if ( bazelOutputFilePtr != nullptr ) {
|
|
||||||
m_data.reporterSpecifications.push_back(
|
|
||||||
{ "junit", std::string( bazelOutputFilePtr ), {}, {} } );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
m_testSpec = parser.testSpec();
|
||||||
|
|
||||||
|
|
||||||
// We now fixup the reporter specs to handle default output spec,
|
// We now fixup the reporter specs to handle default output spec,
|
||||||
// default colour spec, etc
|
// default colour spec, etc
|
||||||
@ -681,6 +703,39 @@ namespace Catch {
|
|||||||
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
|
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
|
||||||
std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
|
std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
|
||||||
|
|
||||||
|
void Config::readBazelEnvVars() {
|
||||||
|
// Register a JUnit reporter for Bazel. Bazel sets an environment
|
||||||
|
// variable with the path to XML output. If this file is written to
|
||||||
|
// during test, Bazel will not generate a default XML output.
|
||||||
|
// This allows the XML output file to contain higher level of detail
|
||||||
|
// than what is possible otherwise.
|
||||||
|
const auto bazelOutputFile = Detail::getEnv( "XML_OUTPUT_FILE" );
|
||||||
|
|
||||||
|
if ( bazelOutputFile ) {
|
||||||
|
m_data.reporterSpecifications.push_back(
|
||||||
|
{ "junit", std::string( bazelOutputFile ), {}, {} } );
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto bazelTestSpec = Detail::getEnv( "TESTBRIDGE_TEST_ONLY" );
|
||||||
|
if ( bazelTestSpec ) {
|
||||||
|
// Presumably the test spec from environment should overwrite
|
||||||
|
// the one we got from CLI (if we got any)
|
||||||
|
m_data.testsOrTags.clear();
|
||||||
|
m_data.testsOrTags.push_back( bazelTestSpec );
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto bazelShardOptions = readBazelShardingOptions();
|
||||||
|
if ( bazelShardOptions ) {
|
||||||
|
std::ofstream f( bazelShardOptions->shardFilePath,
|
||||||
|
std::ios_base::out | std::ios_base::trunc );
|
||||||
|
if ( f.is_open() ) {
|
||||||
|
f << "";
|
||||||
|
m_data.shardIndex = bazelShardOptions->shardIndex;
|
||||||
|
m_data.shardCount = bazelShardOptions->shardCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
|
|
||||||
@ -1472,6 +1527,7 @@ namespace Catch {
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@ -1495,6 +1551,10 @@ namespace Catch {
|
|||||||
return m_wildcardPattern.matches( testCase.name );
|
return m_wildcardPattern.matches( testCase.name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSpec::NamePattern::serializeTo( std::ostream& out ) const {
|
||||||
|
out << '"' << name() << '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
|
TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
|
||||||
: Pattern( filterString )
|
: Pattern( filterString )
|
||||||
@ -1507,6 +1567,10 @@ namespace Catch {
|
|||||||
Tag( m_tag ) ) != end( testCase.tags );
|
Tag( m_tag ) ) != end( testCase.tags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSpec::TagPattern::serializeTo( std::ostream& out ) const {
|
||||||
|
out << name();
|
||||||
|
}
|
||||||
|
|
||||||
bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
|
bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
|
||||||
bool should_use = !testCase.isHidden();
|
bool should_use = !testCase.isHidden();
|
||||||
for (auto const& pattern : m_required) {
|
for (auto const& pattern : m_required) {
|
||||||
@ -1523,18 +1587,31 @@ namespace Catch {
|
|||||||
return should_use;
|
return should_use;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TestSpec::Filter::name() const {
|
void TestSpec::Filter::serializeTo( std::ostream& out ) const {
|
||||||
std::string name;
|
bool first = true;
|
||||||
for (auto const& p : m_required) {
|
for ( auto const& pattern : m_required ) {
|
||||||
name += p->name();
|
if ( !first ) {
|
||||||
|
out << ' ';
|
||||||
|
}
|
||||||
|
out << *pattern;
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
for (auto const& p : m_forbidden) {
|
for ( auto const& pattern : m_forbidden ) {
|
||||||
name += p->name();
|
if ( !first ) {
|
||||||
|
out << ' ';
|
||||||
|
}
|
||||||
|
out << *pattern;
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string TestSpec::extractFilterName( Filter const& filter ) {
|
||||||
|
Catch::ReusableStringStream sstr;
|
||||||
|
sstr << filter;
|
||||||
|
return sstr.str();
|
||||||
|
}
|
||||||
|
|
||||||
bool TestSpec::hasFilters() const {
|
bool TestSpec::hasFilters() const {
|
||||||
return !m_filters.empty();
|
return !m_filters.empty();
|
||||||
}
|
}
|
||||||
@ -1551,7 +1628,7 @@ namespace Catch {
|
|||||||
for( auto const& test : testCases )
|
for( auto const& test : testCases )
|
||||||
if( isThrowSafe( test, config ) && filter.matches( test.getTestCaseInfo() ) )
|
if( isThrowSafe( test, config ) && filter.matches( test.getTestCaseInfo() ) )
|
||||||
currentMatches.emplace_back( &test );
|
currentMatches.emplace_back( &test );
|
||||||
return FilterMatch{ filter.name(), currentMatches };
|
return FilterMatch{ extractFilterName(filter), currentMatches };
|
||||||
} );
|
} );
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
@ -1560,6 +1637,17 @@ namespace Catch {
|
|||||||
return m_invalidSpecs;
|
return m_invalidSpecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSpec::serializeTo( std::ostream& out ) const {
|
||||||
|
bool first = true;
|
||||||
|
for ( auto const& filter : m_filters ) {
|
||||||
|
if ( !first ) {
|
||||||
|
out << ',';
|
||||||
|
}
|
||||||
|
out << filter;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1924,7 +2012,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 3, 1, 1, "", 0 );
|
static Version version( 3, 2, 0, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2175,11 +2263,7 @@ namespace Catch {
|
|||||||
CATCH_BREAK_INTO_DEBUGGER();
|
CATCH_BREAK_INTO_DEBUGGER();
|
||||||
}
|
}
|
||||||
if (m_reaction.shouldThrow) {
|
if (m_reaction.shouldThrow) {
|
||||||
#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
|
throw_test_failure_exception();
|
||||||
throw Catch::TestFailureException();
|
|
||||||
#else
|
|
||||||
CATCH_ERROR( "Test failure requires aborting test!" );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void AssertionHandler::setCompleted() {
|
void AssertionHandler::setCompleted() {
|
||||||
@ -2207,8 +2291,8 @@ namespace Catch {
|
|||||||
|
|
||||||
// This is the overload that takes a string and infers the Equals matcher from it
|
// This is the overload that takes a string and infers the Equals matcher from it
|
||||||
// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
|
// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
|
||||||
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) {
|
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str ) {
|
||||||
handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
|
handleExceptionMatchExpr( handler, Matchers::Equals( str ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
@ -2744,23 +2828,14 @@ namespace Catch {
|
|||||||
return ParserResult::ok(ParseResultType::Matched);
|
return ParserResult::ok(ParseResultType::Matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TRY {
|
// TODO: ideally we should be parsing uint32_t directly
|
||||||
std::size_t parsedTo = 0;
|
// fix this later when we add new parse overload
|
||||||
unsigned long parsedSeed = std::stoul(seed, &parsedTo, 0);
|
auto parsedSeed = parseUInt( seed, 0 );
|
||||||
if (parsedTo != seed.size()) {
|
if ( !parsedSeed ) {
|
||||||
return ParserResult::runtimeError("Could not parse '" + seed + "' as seed");
|
return ParserResult::runtimeError( "Could not parse '" + seed + "' as seed" );
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Ideally we could parse unsigned int directly,
|
|
||||||
// but the stdlib doesn't provide helper for that
|
|
||||||
// type. After this is refactored to use fixed size
|
|
||||||
// type, we should check the parsed value is in range
|
|
||||||
// of the underlying type.
|
|
||||||
config.rngSeed = static_cast<unsigned int>(parsedSeed);
|
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
|
||||||
} CATCH_CATCH_ANON(std::exception const&) {
|
|
||||||
return ParserResult::runtimeError("Could not parse '" + seed + "' as seed");
|
|
||||||
}
|
}
|
||||||
|
config.rngSeed = *parsedSeed;
|
||||||
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
};
|
};
|
||||||
auto const setDefaultColourMode = [&]( std::string const& colourMode ) {
|
auto const setDefaultColourMode = [&]( std::string const& colourMode ) {
|
||||||
Optional<ColourMode> maybeMode = Catch::Detail::stringToColourMode(toLower( colourMode ));
|
Optional<ColourMode> maybeMode = Catch::Detail::stringToColourMode(toLower( colourMode ));
|
||||||
@ -2852,42 +2927,29 @@ namespace Catch {
|
|||||||
return ParserResult::ok( ParseResultType::Matched );
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
};
|
};
|
||||||
auto const setShardCount = [&]( std::string const& shardCount ) {
|
auto const setShardCount = [&]( std::string const& shardCount ) {
|
||||||
CATCH_TRY{
|
auto parsedCount = parseUInt( shardCount );
|
||||||
std::size_t parsedTo = 0;
|
if ( !parsedCount ) {
|
||||||
int64_t parsedCount = std::stoll(shardCount, &parsedTo, 0);
|
return ParserResult::runtimeError(
|
||||||
if (parsedTo != shardCount.size()) {
|
"Could not parse '" + shardCount + "' as shard count" );
|
||||||
return ParserResult::runtimeError("Could not parse '" + shardCount + "' as shard count");
|
|
||||||
}
|
|
||||||
if (parsedCount <= 0) {
|
|
||||||
return ParserResult::runtimeError("Shard count must be a positive number");
|
|
||||||
}
|
|
||||||
|
|
||||||
config.shardCount = static_cast<unsigned int>(parsedCount);
|
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
|
||||||
} CATCH_CATCH_ANON(std::exception const&) {
|
|
||||||
return ParserResult::runtimeError("Could not parse '" + shardCount + "' as shard count");
|
|
||||||
}
|
}
|
||||||
|
if ( *parsedCount == 0 ) {
|
||||||
|
return ParserResult::runtimeError(
|
||||||
|
"Shard count must be positive" );
|
||||||
|
}
|
||||||
|
config.shardCount = *parsedCount;
|
||||||
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
};
|
};
|
||||||
|
|
||||||
auto const setShardIndex = [&](std::string const& shardIndex) {
|
auto const setShardIndex = [&](std::string const& shardIndex) {
|
||||||
CATCH_TRY{
|
auto parsedIndex = parseUInt( shardIndex );
|
||||||
std::size_t parsedTo = 0;
|
if ( !parsedIndex ) {
|
||||||
int64_t parsedIndex = std::stoll(shardIndex, &parsedTo, 0);
|
return ParserResult::runtimeError(
|
||||||
if (parsedTo != shardIndex.size()) {
|
"Could not parse '" + shardIndex + "' as shard index" );
|
||||||
return ParserResult::runtimeError("Could not parse '" + shardIndex + "' as shard index");
|
|
||||||
}
|
|
||||||
if (parsedIndex < 0) {
|
|
||||||
return ParserResult::runtimeError("Shard index must be a non-negative number");
|
|
||||||
}
|
|
||||||
|
|
||||||
config.shardIndex = static_cast<unsigned int>(parsedIndex);
|
|
||||||
return ParserResult::ok(ParseResultType::Matched);
|
|
||||||
} CATCH_CATCH_ANON(std::exception const&) {
|
|
||||||
return ParserResult::runtimeError("Could not parse '" + shardIndex + "' as shard index");
|
|
||||||
}
|
}
|
||||||
|
config.shardIndex = *parsedIndex;
|
||||||
|
return ParserResult::ok( ParseResultType::Matched );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
auto cli
|
auto cli
|
||||||
= ExeName( config.processName )
|
= ExeName( config.processName )
|
||||||
| Help( config.showHelp )
|
| Help( config.showHelp )
|
||||||
@ -3925,6 +3987,35 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
namespace Detail {
|
||||||
|
|
||||||
|
#if !defined (CATCH_CONFIG_GETENV)
|
||||||
|
char const* getEnv( char const* ) { return nullptr; }
|
||||||
|
#else
|
||||||
|
|
||||||
|
char const* getEnv( char const* varName ) {
|
||||||
|
# if defined( _MSC_VER )
|
||||||
|
# pragma warning( push )
|
||||||
|
# pragma warning( disable : 4996 ) // use getenv_s instead of getenv
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return std::getenv( varName );
|
||||||
|
|
||||||
|
# if defined( _MSC_VER )
|
||||||
|
# pragma warning( pop )
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // namespace Detail
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -4418,6 +4509,47 @@ namespace Catch {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
Optional<unsigned int> parseUInt(std::string const& input, int base) {
|
||||||
|
auto trimmed = trim( input );
|
||||||
|
// std::stoull is annoying and accepts numbers starting with '-',
|
||||||
|
// it just negates them into unsigned int
|
||||||
|
if ( trimmed.empty() || trimmed[0] == '-' ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
CATCH_TRY {
|
||||||
|
size_t pos = 0;
|
||||||
|
const auto ret = std::stoull( trimmed, &pos, base );
|
||||||
|
|
||||||
|
// We did not consume the whole input, so there is an issue
|
||||||
|
// This can be bunch of different stuff, like multiple numbers
|
||||||
|
// in the input, or invalid digits/characters and so on. Either
|
||||||
|
// way, we do not want to return the partially parsed result.
|
||||||
|
if ( pos != trimmed.size() ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
// Too large
|
||||||
|
if ( ret > std::numeric_limits<unsigned int>::max() ) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return static_cast<unsigned int>(ret);
|
||||||
|
} CATCH_CATCH_ANON( std::exception const& ) {
|
||||||
|
// There was a larger issue with the input, e.g. the parsed
|
||||||
|
// number would be too large to fit within ull.
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
@ -5885,7 +6017,7 @@ namespace Catch {
|
|||||||
TestCaseInfo const* rhs ) {
|
TestCaseInfo const* rhs ) {
|
||||||
return *lhs < *rhs;
|
return *lhs < *rhs;
|
||||||
};
|
};
|
||||||
std::set<TestCaseInfo const*, decltype(testInfoCmp)> seenTests(testInfoCmp);
|
std::set<TestCaseInfo const*, decltype(testInfoCmp) &> seenTests(testInfoCmp);
|
||||||
for ( auto const& test : tests ) {
|
for ( auto const& test : tests ) {
|
||||||
const auto infoPtr = &test.getTestCaseInfo();
|
const auto infoPtr = &test.getTestCaseInfo();
|
||||||
const auto prev = seenTests.insert( infoPtr );
|
const auto prev = seenTests.insert( infoPtr );
|
||||||
@ -6190,6 +6322,21 @@ namespace TestCaseTracking {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
void throw_test_failure_exception() {
|
||||||
|
#if !defined( CATCH_CONFIG_DISABLE_EXCEPTIONS )
|
||||||
|
throw TestFailureException{};
|
||||||
|
#else
|
||||||
|
CATCH_ERROR( "Test failure requires aborting test!" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
@ -6476,10 +6623,6 @@ namespace Catch {
|
|||||||
m_mode = None;
|
m_mode = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestSpec parseTestSpec( std::string const& arg ) {
|
|
||||||
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
|
|
||||||
@ -7588,9 +7731,9 @@ namespace Catch {
|
|||||||
// This is the general overload that takes a any string matcher
|
// This is the general overload that takes a any string matcher
|
||||||
// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
|
// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
|
||||||
// the Equals matcher (so the header does not mention matchers)
|
// the Equals matcher (so the header does not mention matchers)
|
||||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) {
|
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher ) {
|
||||||
std::string exceptionMessage = Catch::translateActiveException();
|
std::string exceptionMessage = Catch::translateActiveException();
|
||||||
MatchExpr<std::string, StringMatcher const&> expr( CATCH_MOVE(exceptionMessage), matcher, matcherString );
|
MatchExpr<std::string, StringMatcher const&> expr( CATCH_MOVE(exceptionMessage), matcher );
|
||||||
handler.handleExpr( expr );
|
handler.handleExpr( expr );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7669,22 +7812,6 @@ namespace Catch {
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr Catch::StringRef bothOrAll( std::uint64_t count ) {
|
|
||||||
switch (count) {
|
|
||||||
case 1:
|
|
||||||
return Catch::StringRef{};
|
|
||||||
case 2:
|
|
||||||
return "both "_catch_sr;
|
|
||||||
default:
|
|
||||||
return "all "_catch_sr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anon namespace
|
|
||||||
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -7699,42 +7826,6 @@ namespace {
|
|||||||
static constexpr Catch::StringRef compactPassedString = "passed"_sr;
|
static constexpr Catch::StringRef compactPassedString = "passed"_sr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Colour, message variants:
|
|
||||||
// - white: No tests ran.
|
|
||||||
// - red: Failed [both/all] N test cases, failed [both/all] M assertions.
|
|
||||||
// - white: Passed [both/all] N test cases (no assertions).
|
|
||||||
// - red: Failed N tests cases, failed M assertions.
|
|
||||||
// - green: Passed [both/all] N tests cases with M assertions.
|
|
||||||
void printTotals(std::ostream& out, const Totals& totals, ColourImpl* colourImpl) {
|
|
||||||
if (totals.testCases.total() == 0) {
|
|
||||||
out << "No tests ran.";
|
|
||||||
} else if (totals.testCases.failed == totals.testCases.total()) {
|
|
||||||
auto guard = colourImpl->guardColour( Colour::ResultError ).engage( out );
|
|
||||||
const StringRef qualify_assertions_failed =
|
|
||||||
totals.assertions.failed == totals.assertions.total() ?
|
|
||||||
bothOrAll(totals.assertions.failed) : StringRef{};
|
|
||||||
out <<
|
|
||||||
"Failed " << bothOrAll(totals.testCases.failed)
|
|
||||||
<< pluralise(totals.testCases.failed, "test case"_sr) << ", "
|
|
||||||
"failed " << qualify_assertions_failed <<
|
|
||||||
pluralise(totals.assertions.failed, "assertion"_sr) << '.';
|
|
||||||
} else if (totals.assertions.total() == 0) {
|
|
||||||
out <<
|
|
||||||
"Passed " << bothOrAll(totals.testCases.total())
|
|
||||||
<< pluralise(totals.testCases.total(), "test case"_sr)
|
|
||||||
<< " (no assertions).";
|
|
||||||
} else if (totals.assertions.failed) {
|
|
||||||
out << colourImpl->guardColour( Colour::ResultError ) <<
|
|
||||||
"Failed " << pluralise(totals.testCases.failed, "test case"_sr) << ", "
|
|
||||||
"failed " << pluralise(totals.assertions.failed, "assertion"_sr) << '.';
|
|
||||||
} else {
|
|
||||||
out << colourImpl->guardColour( Colour::ResultSuccess ) <<
|
|
||||||
"Passed " << bothOrAll(totals.testCases.passed)
|
|
||||||
<< pluralise(totals.testCases.passed, "test case"_sr) <<
|
|
||||||
" with " << pluralise(totals.assertions.passed, "assertion"_sr) << '.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation of CompactReporter formatting
|
// Implementation of CompactReporter formatting
|
||||||
class AssertionPrinter {
|
class AssertionPrinter {
|
||||||
public:
|
public:
|
||||||
@ -7910,7 +8001,7 @@ private:
|
|||||||
if ( m_config->testSpec().hasFilters() ) {
|
if ( m_config->testSpec().hasFilters() ) {
|
||||||
m_stream << m_colour->guardColour( Colour::BrightYellow )
|
m_stream << m_colour->guardColour( Colour::BrightYellow )
|
||||||
<< "Filters: "
|
<< "Filters: "
|
||||||
<< serializeFilters( m_config->getTestsOrTags() )
|
<< m_config->testSpec()
|
||||||
<< '\n';
|
<< '\n';
|
||||||
}
|
}
|
||||||
m_stream << "RNG seed: " << getSeed() << '\n';
|
m_stream << "RNG seed: " << getSeed() << '\n';
|
||||||
@ -7942,7 +8033,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
|
void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {
|
||||||
printTotals( m_stream, _testRunStats.totals, m_colour.get() );
|
printTestRunTotals( m_stream, *m_colour, _testRunStats.totals );
|
||||||
m_stream << "\n\n" << std::flush;
|
m_stream << "\n\n" << std::flush;
|
||||||
StreamingReporterBase::testRunEnded( _testRunStats );
|
StreamingReporterBase::testRunEnded( _testRunStats );
|
||||||
}
|
}
|
||||||
@ -8424,7 +8515,7 @@ void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
|
|||||||
}
|
}
|
||||||
void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
|
void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
|
||||||
printTotalsDivider(_testRunStats.totals);
|
printTotalsDivider(_testRunStats.totals);
|
||||||
printTotals(_testRunStats.totals);
|
printTestRunTotals( m_stream, *m_colour, _testRunStats.totals );
|
||||||
m_stream << '\n' << std::flush;
|
m_stream << '\n' << std::flush;
|
||||||
StreamingReporterBase::testRunEnded(_testRunStats);
|
StreamingReporterBase::testRunEnded(_testRunStats);
|
||||||
}
|
}
|
||||||
@ -8432,7 +8523,7 @@ void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
|
|||||||
StreamingReporterBase::testRunStarting(_testInfo);
|
StreamingReporterBase::testRunStarting(_testInfo);
|
||||||
if ( m_config->testSpec().hasFilters() ) {
|
if ( m_config->testSpec().hasFilters() ) {
|
||||||
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
|
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
|
||||||
<< serializeFilters( m_config->getTestsOrTags() ) << '\n';
|
<< m_config->testSpec() << '\n';
|
||||||
}
|
}
|
||||||
m_stream << "Randomness seeded to: " << getSeed() << '\n';
|
m_stream << "Randomness seeded to: " << getSeed() << '\n';
|
||||||
}
|
}
|
||||||
@ -8531,82 +8622,6 @@ void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t
|
|||||||
<< '\n';
|
<< '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SummaryColumn {
|
|
||||||
|
|
||||||
SummaryColumn( std::string _label, Colour::Code _colour )
|
|
||||||
: label( CATCH_MOVE( _label ) ),
|
|
||||||
colour( _colour ) {}
|
|
||||||
SummaryColumn addRow( std::uint64_t count ) {
|
|
||||||
ReusableStringStream rss;
|
|
||||||
rss << count;
|
|
||||||
std::string row = rss.str();
|
|
||||||
for (auto& oldRow : rows) {
|
|
||||||
while (oldRow.size() < row.size())
|
|
||||||
oldRow = ' ' + oldRow;
|
|
||||||
while (oldRow.size() > row.size())
|
|
||||||
row = ' ' + row;
|
|
||||||
}
|
|
||||||
rows.push_back(row);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string label;
|
|
||||||
Colour::Code colour;
|
|
||||||
std::vector<std::string> rows;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void ConsoleReporter::printTotals( Totals const& totals ) {
|
|
||||||
if (totals.testCases.total() == 0) {
|
|
||||||
m_stream << m_colour->guardColour( Colour::Warning )
|
|
||||||
<< "No tests ran\n";
|
|
||||||
} else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {
|
|
||||||
m_stream << m_colour->guardColour( Colour::ResultSuccess )
|
|
||||||
<< "All tests passed";
|
|
||||||
m_stream << " ("
|
|
||||||
<< pluralise(totals.assertions.passed, "assertion"_sr) << " in "
|
|
||||||
<< pluralise(totals.testCases.passed, "test case"_sr) << ')'
|
|
||||||
<< '\n';
|
|
||||||
} else {
|
|
||||||
|
|
||||||
std::vector<SummaryColumn> columns;
|
|
||||||
columns.push_back(SummaryColumn("", Colour::None)
|
|
||||||
.addRow(totals.testCases.total())
|
|
||||||
.addRow(totals.assertions.total()));
|
|
||||||
columns.push_back(SummaryColumn("passed", Colour::Success)
|
|
||||||
.addRow(totals.testCases.passed)
|
|
||||||
.addRow(totals.assertions.passed));
|
|
||||||
columns.push_back(SummaryColumn("failed", Colour::ResultError)
|
|
||||||
.addRow(totals.testCases.failed)
|
|
||||||
.addRow(totals.assertions.failed));
|
|
||||||
columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure)
|
|
||||||
.addRow(totals.testCases.failedButOk)
|
|
||||||
.addRow(totals.assertions.failedButOk));
|
|
||||||
|
|
||||||
printSummaryRow("test cases"_sr, columns, 0);
|
|
||||||
printSummaryRow("assertions"_sr, columns, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ConsoleReporter::printSummaryRow(StringRef label, std::vector<SummaryColumn> const& cols, std::size_t row) {
|
|
||||||
for (auto col : cols) {
|
|
||||||
std::string const& value = col.rows[row];
|
|
||||||
if (col.label.empty()) {
|
|
||||||
m_stream << label << ": ";
|
|
||||||
if ( value != "0" ) {
|
|
||||||
m_stream << value;
|
|
||||||
} else {
|
|
||||||
m_stream << m_colour->guardColour( Colour::Warning )
|
|
||||||
<< "- none -";
|
|
||||||
}
|
|
||||||
} else if (value != "0") {
|
|
||||||
m_stream << m_colour->guardColour( Colour::LightGrey ) << " | "
|
|
||||||
<< m_colour->guardColour( col.colour ) << value << ' '
|
|
||||||
<< col.label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_stream << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleReporter::printTotalsDivider(Totals const& totals) {
|
void ConsoleReporter::printTotalsDivider(Totals const& totals) {
|
||||||
if (totals.testCases.total() > 0) {
|
if (totals.testCases.total() > 0) {
|
||||||
std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
|
std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());
|
||||||
@ -8634,9 +8649,6 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
|
|||||||
}
|
}
|
||||||
m_stream << '\n';
|
m_stream << '\n';
|
||||||
}
|
}
|
||||||
void ConsoleReporter::printSummaryDivider() {
|
|
||||||
m_stream << lineOfChars('-') << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
@ -9054,6 +9066,104 @@ namespace Catch {
|
|||||||
out << "\n\n" << std::flush;
|
out << "\n\n" << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class SummaryColumn {
|
||||||
|
public:
|
||||||
|
SummaryColumn( std::string suffix, Colour::Code colour ):
|
||||||
|
m_suffix( CATCH_MOVE( suffix ) ), m_colour( colour ) {}
|
||||||
|
|
||||||
|
SummaryColumn&& addRow( std::uint64_t count ) && {
|
||||||
|
std::string row = std::to_string(count);
|
||||||
|
auto const new_width = std::max( m_width, row.size() );
|
||||||
|
if ( new_width > m_width ) {
|
||||||
|
for ( auto& oldRow : m_rows ) {
|
||||||
|
oldRow.insert( 0, new_width - m_width, ' ' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
row.insert( 0, m_width - row.size(), ' ' );
|
||||||
|
}
|
||||||
|
m_width = new_width;
|
||||||
|
m_rows.push_back( row );
|
||||||
|
return std::move( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const& getSuffix() const { return m_suffix; }
|
||||||
|
Colour::Code getColour() const { return m_colour; }
|
||||||
|
std::string const& getRow( std::size_t index ) const {
|
||||||
|
return m_rows[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_suffix;
|
||||||
|
Colour::Code m_colour;
|
||||||
|
std::size_t m_width = 0;
|
||||||
|
std::vector<std::string> m_rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
void printSummaryRow( std::ostream& stream,
|
||||||
|
ColourImpl& colour,
|
||||||
|
StringRef label,
|
||||||
|
std::vector<SummaryColumn> const& cols,
|
||||||
|
std::size_t row ) {
|
||||||
|
for ( auto const& col : cols ) {
|
||||||
|
auto const& value = col.getRow( row );
|
||||||
|
auto const& suffix = col.getSuffix();
|
||||||
|
if ( suffix.empty() ) {
|
||||||
|
stream << label << ": ";
|
||||||
|
if ( value != "0" ) {
|
||||||
|
stream << value;
|
||||||
|
} else {
|
||||||
|
stream << colour.guardColour( Colour::Warning )
|
||||||
|
<< "- none -";
|
||||||
|
}
|
||||||
|
} else if ( value != "0" ) {
|
||||||
|
stream << colour.guardColour( Colour::LightGrey ) << " | "
|
||||||
|
<< colour.guardColour( col.getColour() ) << value
|
||||||
|
<< ' ' << suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream << '\n';
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void printTestRunTotals( std::ostream& stream,
|
||||||
|
ColourImpl& streamColour,
|
||||||
|
Totals const& totals ) {
|
||||||
|
if ( totals.testCases.total() == 0 ) {
|
||||||
|
stream << streamColour.guardColour( Colour::Warning )
|
||||||
|
<< "No tests ran\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
|
||||||
|
stream << streamColour.guardColour( Colour::ResultSuccess )
|
||||||
|
<< "All tests passed";
|
||||||
|
stream << " ("
|
||||||
|
<< pluralise( totals.assertions.passed, "assertion"_sr )
|
||||||
|
<< " in "
|
||||||
|
<< pluralise( totals.testCases.passed, "test case"_sr )
|
||||||
|
<< ')' << '\n';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SummaryColumn> columns;
|
||||||
|
columns.push_back( SummaryColumn( "", Colour::None )
|
||||||
|
.addRow( totals.testCases.total() )
|
||||||
|
.addRow( totals.assertions.total() ) );
|
||||||
|
columns.push_back( SummaryColumn( "passed", Colour::Success )
|
||||||
|
.addRow( totals.testCases.passed )
|
||||||
|
.addRow( totals.assertions.passed ) );
|
||||||
|
columns.push_back( SummaryColumn( "failed", Colour::ResultError )
|
||||||
|
.addRow( totals.testCases.failed )
|
||||||
|
.addRow( totals.assertions.failed ) );
|
||||||
|
columns.push_back(
|
||||||
|
SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
|
||||||
|
.addRow( totals.testCases.failedButOk )
|
||||||
|
.addRow( totals.assertions.failedButOk ) );
|
||||||
|
printSummaryRow( stream, streamColour, "test cases"_sr, columns, 0 );
|
||||||
|
printSummaryRow( stream, streamColour, "assertions"_sr, columns, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
|
|
||||||
@ -9074,6 +9184,8 @@ namespace Catch {
|
|||||||
std::tm timeInfo = {};
|
std::tm timeInfo = {};
|
||||||
#if defined (_MSC_VER) || defined (__MINGW32__)
|
#if defined (_MSC_VER) || defined (__MINGW32__)
|
||||||
gmtime_s(&timeInfo, &rawtime);
|
gmtime_s(&timeInfo, &rawtime);
|
||||||
|
#elif defined (CATCH_PLATFORM_PLAYSTATION)
|
||||||
|
gmtime_s(&rawtime, &timeInfo);
|
||||||
#else
|
#else
|
||||||
gmtime_r(&rawtime, &timeInfo);
|
gmtime_r(&rawtime, &timeInfo);
|
||||||
#endif
|
#endif
|
||||||
@ -9187,10 +9299,10 @@ namespace Catch {
|
|||||||
xml.scopedElement("property")
|
xml.scopedElement("property")
|
||||||
.writeAttribute("name"_sr, "random-seed"_sr)
|
.writeAttribute("name"_sr, "random-seed"_sr)
|
||||||
.writeAttribute("value"_sr, m_config->rngSeed());
|
.writeAttribute("value"_sr, m_config->rngSeed());
|
||||||
if (m_config->hasTestFilters()) {
|
if (m_config->testSpec().hasFilters()) {
|
||||||
xml.scopedElement("property")
|
xml.scopedElement("property")
|
||||||
.writeAttribute("name"_sr, "filters"_sr)
|
.writeAttribute("name"_sr, "filters"_sr)
|
||||||
.writeAttribute("value"_sr, serializeFilters(m_config->getTestsOrTags()));
|
.writeAttribute("value"_sr, m_config->testSpec());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9563,9 +9675,14 @@ namespace Catch {
|
|||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string createRngSeedString(uint32_t seed) {
|
std::string createMetadataString(IConfig const& config) {
|
||||||
ReusableStringStream sstr;
|
ReusableStringStream sstr;
|
||||||
sstr << "rng-seed=" << seed;
|
if ( config.testSpec().hasFilters() ) {
|
||||||
|
sstr << "filters='"
|
||||||
|
<< config.testSpec()
|
||||||
|
<< "' ";
|
||||||
|
}
|
||||||
|
sstr << "rng-seed=" << config.rngSeed();
|
||||||
return sstr.str();
|
return sstr.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9573,7 +9690,7 @@ namespace Catch {
|
|||||||
void SonarQubeReporter::testRunStarting(TestRunInfo const& testRunInfo) {
|
void SonarQubeReporter::testRunStarting(TestRunInfo const& testRunInfo) {
|
||||||
CumulativeReporterBase::testRunStarting(testRunInfo);
|
CumulativeReporterBase::testRunStarting(testRunInfo);
|
||||||
|
|
||||||
xml.writeComment( createRngSeedString( m_config->rngSeed() ) );
|
xml.writeComment( createMetadataString( *m_config ) );
|
||||||
xml.startElement("testExecutions");
|
xml.startElement("testExecutions");
|
||||||
xml.writeAttribute("version"_sr, '1');
|
xml.writeAttribute("version"_sr, '1');
|
||||||
}
|
}
|
||||||
@ -9893,6 +10010,9 @@ namespace Catch {
|
|||||||
} // End anonymous namespace
|
} // End anonymous namespace
|
||||||
|
|
||||||
void TAPReporter::testRunStarting( TestRunInfo const& ) {
|
void TAPReporter::testRunStarting( TestRunInfo const& ) {
|
||||||
|
if ( m_config->testSpec().hasFilters() ) {
|
||||||
|
m_stream << "# filters: " << m_config->testSpec() << '\n';
|
||||||
|
}
|
||||||
m_stream << "# rng-seed: " << m_config->rngSeed() << '\n';
|
m_stream << "# rng-seed: " << m_config->rngSeed() << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10131,9 +10251,11 @@ namespace Catch {
|
|||||||
m_xml.startElement("Catch2TestRun")
|
m_xml.startElement("Catch2TestRun")
|
||||||
.writeAttribute("name"_sr, m_config->name())
|
.writeAttribute("name"_sr, m_config->name())
|
||||||
.writeAttribute("rng-seed"_sr, m_config->rngSeed())
|
.writeAttribute("rng-seed"_sr, m_config->rngSeed())
|
||||||
|
.writeAttribute("xml-format-version"_sr, 2)
|
||||||
.writeAttribute("catch2-version"_sr, libraryVersion());
|
.writeAttribute("catch2-version"_sr, libraryVersion());
|
||||||
if (m_config->testSpec().hasFilters())
|
if ( m_config->testSpec().hasFilters() ) {
|
||||||
m_xml.writeAttribute( "filters"_sr, serializeFilters( m_config->getTestsOrTags() ) );
|
m_xml.writeAttribute( "filters"_sr, m_config->testSpec() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
|
void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
|
||||||
// Catch v3.1.1
|
// Catch v3.2.0
|
||||||
// Generated: 2022-10-17 18:47:20.510385
|
// Generated: 2022-11-16 19:30:14.116909
|
||||||
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
||||||
// This file is an amalgamation of multiple different files.
|
// This file is an amalgamation of multiple different files.
|
||||||
// You probably shouldn't edit it directly.
|
// You probably shouldn't edit it directly.
|
||||||
@ -330,6 +330,10 @@ namespace Catch {
|
|||||||
# if defined( WINAPI_FAMILY ) && ( WINAPI_FAMILY == WINAPI_FAMILY_APP )
|
# if defined( WINAPI_FAMILY ) && ( WINAPI_FAMILY == WINAPI_FAMILY_APP )
|
||||||
# define CATCH_PLATFORM_WINDOWS_UWP
|
# define CATCH_PLATFORM_WINDOWS_UWP
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
#elif defined(__ORBIS__) || defined(__PROSPERO__)
|
||||||
|
# define CATCH_PLATFORM_PLAYSTATION
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // CATCH_PLATFORM_HPP_INCLUDED
|
#endif // CATCH_PLATFORM_HPP_INCLUDED
|
||||||
@ -421,23 +425,32 @@ namespace Catch {
|
|||||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
||||||
_Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
|
_Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
|
||||||
|
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
|
||||||
|
_Pragma( "clang diagnostic ignored \"-Wcomma\"" )
|
||||||
|
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Assume that non-Windows platforms support posix signals by default
|
// We know some environments not to support full POSIX signals
|
||||||
#if !defined(CATCH_PLATFORM_WINDOWS)
|
#if defined( CATCH_PLATFORM_WINDOWS ) || \
|
||||||
#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
|
defined( CATCH_PLATFORM_PLAYSTATION ) || \
|
||||||
|
defined( __CYGWIN__ ) || \
|
||||||
|
defined( __QNX__ ) || \
|
||||||
|
defined( __EMSCRIPTEN__ ) || \
|
||||||
|
defined( __DJGPP__ ) || \
|
||||||
|
defined( __OS400__ )
|
||||||
|
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#else
|
||||||
|
# define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// We know some environments not to support full POSIX signals
|
// Assume that some platforms do not support getenv.
|
||||||
#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
|
#if defined(CATCH_PLATFORM_WINDOWS_UWP) || defined(CATCH_PLATFORM_PLAYSTATION)
|
||||||
#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
|
# define CATCH_INTERNAL_CONFIG_NO_GETENV
|
||||||
#endif
|
#else
|
||||||
|
# define CATCH_INTERNAL_CONFIG_GETENV
|
||||||
#ifdef __OS400__
|
|
||||||
# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -580,6 +593,10 @@ namespace Catch {
|
|||||||
# define CATCH_CONFIG_POSIX_SIGNALS
|
# define CATCH_CONFIG_POSIX_SIGNALS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CATCH_INTERNAL_CONFIG_GETENV) && !defined(CATCH_INTERNAL_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_NO_GETENV) && !defined(CATCH_CONFIG_GETENV)
|
||||||
|
# define CATCH_CONFIG_GETENV
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
|
#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
|
||||||
# define CATCH_CONFIG_CPP11_TO_STRING
|
# define CATCH_CONFIG_CPP11_TO_STRING
|
||||||
#endif
|
#endif
|
||||||
@ -668,6 +685,10 @@ namespace Catch {
|
|||||||
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
|
# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS)
|
||||||
|
# define CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
|
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
|
||||||
#define CATCH_TRY if ((true))
|
#define CATCH_TRY if ((true))
|
||||||
#define CATCH_CATCH_ALL if ((false))
|
#define CATCH_CATCH_ALL if ((false))
|
||||||
@ -1720,6 +1741,13 @@ namespace Catch {
|
|||||||
//! Used to signal that an assertion macro failed
|
//! Used to signal that an assertion macro failed
|
||||||
struct TestFailureException{};
|
struct TestFailureException{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outlines throwing of `TestFailureException` into a single TU
|
||||||
|
*
|
||||||
|
* Also handles `CATCH_CONFIG_DISABLE_EXCEPTIONS` for callers.
|
||||||
|
*/
|
||||||
|
[[noreturn]] void throw_test_failure_exception();
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
|
#endif // CATCH_TEST_FAILURE_EXCEPTION_HPP_INCLUDED
|
||||||
@ -3766,6 +3794,7 @@ namespace Catch
|
|||||||
|
|
||||||
#endif // CATCH_WILDCARD_PATTERN_HPP_INCLUDED
|
#endif // CATCH_WILDCARD_PATTERN_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -3784,6 +3813,14 @@ namespace Catch {
|
|||||||
virtual bool matches( TestCaseInfo const& testCase ) const = 0;
|
virtual bool matches( TestCaseInfo const& testCase ) const = 0;
|
||||||
std::string const& name() const;
|
std::string const& name() const;
|
||||||
private:
|
private:
|
||||||
|
virtual void serializeTo( std::ostream& out ) const = 0;
|
||||||
|
// Writes string that would be reparsed into the pattern
|
||||||
|
friend std::ostream& operator<<(std::ostream& out,
|
||||||
|
Pattern const& pattern) {
|
||||||
|
pattern.serializeTo( out );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
std::string const m_name;
|
std::string const m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3792,6 +3829,8 @@ namespace Catch {
|
|||||||
explicit NamePattern( std::string const& name, std::string const& filterString );
|
explicit NamePattern( std::string const& name, std::string const& filterString );
|
||||||
bool matches( TestCaseInfo const& testCase ) const override;
|
bool matches( TestCaseInfo const& testCase ) const override;
|
||||||
private:
|
private:
|
||||||
|
void serializeTo( std::ostream& out ) const override;
|
||||||
|
|
||||||
WildcardPattern m_wildcardPattern;
|
WildcardPattern m_wildcardPattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3800,6 +3839,8 @@ namespace Catch {
|
|||||||
explicit TagPattern( std::string const& tag, std::string const& filterString );
|
explicit TagPattern( std::string const& tag, std::string const& filterString );
|
||||||
bool matches( TestCaseInfo const& testCase ) const override;
|
bool matches( TestCaseInfo const& testCase ) const override;
|
||||||
private:
|
private:
|
||||||
|
void serializeTo( std::ostream& out ) const override;
|
||||||
|
|
||||||
std::string m_tag;
|
std::string m_tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3807,10 +3848,19 @@ namespace Catch {
|
|||||||
std::vector<Detail::unique_ptr<Pattern>> m_required;
|
std::vector<Detail::unique_ptr<Pattern>> m_required;
|
||||||
std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
|
std::vector<Detail::unique_ptr<Pattern>> m_forbidden;
|
||||||
|
|
||||||
|
//! Serializes this filter into a string that would be parsed into
|
||||||
|
//! an equivalent filter
|
||||||
|
void serializeTo( std::ostream& out ) const;
|
||||||
|
friend std::ostream& operator<<(std::ostream& out, Filter const& f) {
|
||||||
|
f.serializeTo( out );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
bool matches( TestCaseInfo const& testCase ) const;
|
bool matches( TestCaseInfo const& testCase ) const;
|
||||||
std::string name() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::string extractFilterName( Filter const& filter );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct FilterMatch {
|
struct FilterMatch {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -3827,7 +3877,16 @@ namespace Catch {
|
|||||||
private:
|
private:
|
||||||
std::vector<Filter> m_filters;
|
std::vector<Filter> m_filters;
|
||||||
std::vector<std::string> m_invalidSpecs;
|
std::vector<std::string> m_invalidSpecs;
|
||||||
|
|
||||||
friend class TestSpecParser;
|
friend class TestSpecParser;
|
||||||
|
//! Serializes this test spec into a string that would be parsed into
|
||||||
|
//! equivalent test spec
|
||||||
|
void serializeTo( std::ostream& out ) const;
|
||||||
|
friend std::ostream& operator<<(std::ostream& out,
|
||||||
|
TestSpec const& spec) {
|
||||||
|
spec.serializeTo( out );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4288,6 +4347,9 @@ namespace Catch {
|
|||||||
std::chrono::milliseconds benchmarkWarmupTime() const override;
|
std::chrono::milliseconds benchmarkWarmupTime() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Reads Bazel env vars and applies them to the config
|
||||||
|
void readBazelEnvVars();
|
||||||
|
|
||||||
ConfigData m_data;
|
ConfigData m_data;
|
||||||
std::vector<ProcessedReporterSpec> m_processedReporterSpecs;
|
std::vector<ProcessedReporterSpec> m_processedReporterSpecs;
|
||||||
TestSpec m_testSpec;
|
TestSpec m_testSpec;
|
||||||
@ -4427,7 +4489,7 @@ namespace Catch {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#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 )
|
const 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 ) \
|
#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \
|
||||||
@ -5308,6 +5370,66 @@ namespace Catch {
|
|||||||
#define CATCH_DECOMPOSER_HPP_INCLUDED
|
#define CATCH_DECOMPOSER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CATCH_COMPARE_TRAITS_HPP_INCLUDED
|
||||||
|
#define CATCH_COMPARE_TRAITS_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
namespace Detail {
|
||||||
|
|
||||||
|
#if defined( __GNUC__ ) && !defined( __clang__ )
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
// GCC likes to complain about comparing bool with 0, in the decltype()
|
||||||
|
// that defines the comparable traits below.
|
||||||
|
# pragma GCC diagnostic ignored "-Wbool-compare"
|
||||||
|
// "ordered comparison of pointer with integer zero" same as above,
|
||||||
|
// but it does not have a separate warning flag to suppress
|
||||||
|
# pragma GCC diagnostic ignored "-Wextra"
|
||||||
|
// Did you know that comparing floats with `0` directly
|
||||||
|
// is super-duper dangerous in unevaluated context?
|
||||||
|
# pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CATCH_DEFINE_COMPARABLE_TRAIT( id, op ) \
|
||||||
|
template <typename, typename, typename = void> \
|
||||||
|
struct is_##id##_comparable : std::false_type {}; \
|
||||||
|
template <typename T, typename U> \
|
||||||
|
struct is_##id##_comparable< \
|
||||||
|
T, \
|
||||||
|
U, \
|
||||||
|
void_t<decltype( std::declval<T>() op std::declval<U>() )>> \
|
||||||
|
: std::true_type {}; \
|
||||||
|
template <typename, typename = void> \
|
||||||
|
struct is_##id##_0_comparable : std::false_type {}; \
|
||||||
|
template <typename T> \
|
||||||
|
struct is_##id##_0_comparable<T, \
|
||||||
|
void_t<decltype( std::declval<T>() op 0 )>> \
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
// We need all 6 pre-spaceship comparison ops: <, <=, >, >=, ==, !=
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( lt, < )
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( le, <= )
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( gt, > )
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( ge, >= )
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( eq, == )
|
||||||
|
CATCH_DEFINE_COMPARABLE_TRAIT( ne, != )
|
||||||
|
|
||||||
|
#undef CATCH_DEFINE_COMPARABLE_TRAIT
|
||||||
|
|
||||||
|
#if defined( __GNUC__ ) && !defined( __clang__ )
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Detail
|
||||||
|
} // namespace Catch
|
||||||
|
|
||||||
|
#endif // CATCH_COMPARE_TRAITS_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -5451,53 +5573,129 @@ namespace Catch {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)
|
|
||||||
template<typename LhsT, typename RhsT>
|
|
||||||
auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
|
||||||
template<typename T>
|
|
||||||
auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }
|
|
||||||
|
|
||||||
template<typename LhsT, typename RhsT>
|
|
||||||
auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }
|
|
||||||
template<typename T>
|
|
||||||
auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
|
|
||||||
template<typename T>
|
|
||||||
auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }
|
|
||||||
|
|
||||||
|
|
||||||
template<typename LhsT>
|
template<typename LhsT>
|
||||||
class ExprLhs {
|
class ExprLhs {
|
||||||
LhsT m_lhs;
|
LhsT m_lhs;
|
||||||
public:
|
public:
|
||||||
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||||
|
|
||||||
template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0>
|
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
|
||||||
friend auto operator == ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> {
|
template < \
|
||||||
return { compareEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "=="_sr, rhs };
|
typename RhsT, \
|
||||||
}
|
std::enable_if_t< \
|
||||||
template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0>
|
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
friend auto operator == ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> {
|
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||||
return { compareEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "=="_sr, rhs };
|
int> = 0> \
|
||||||
}
|
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT const&> { \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
std::is_arithmetic<RhsT>::value, \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
Detail::is_eq_0_comparable<LhsT>:: \
|
||||||
|
value && /* We allow long because we want \
|
||||||
|
`ptr op NULL to be accepted */ \
|
||||||
|
( std::is_same<RhsT, int>::value || \
|
||||||
|
std::is_same<RhsT, long>::value ), \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
if ( rhs != 0 ) { \
|
||||||
|
throw_test_failure_exception(); \
|
||||||
|
} \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
Detail::is_eq_0_comparable<RhsT>:: \
|
||||||
|
value && /* We allow long because we want \
|
||||||
|
`ptr op NULL` to be accepted */ \
|
||||||
|
( std::is_same<LhsT, int>::value || \
|
||||||
|
std::is_same<LhsT, long>::value ), \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
if ( lhs.m_lhs != 0 ) { \
|
||||||
|
throw_test_failure_exception(); \
|
||||||
|
} \
|
||||||
|
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
}
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( eq, == )
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( ne, != )
|
||||||
|
|
||||||
|
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
|
||||||
|
|
||||||
|
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t< \
|
||||||
|
Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT const&> { \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
std::is_arithmetic<RhsT>::value, \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
Detail::is_##id##_0_comparable<LhsT>::value && \
|
||||||
|
std::is_same<RhsT, int>::value, \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
if ( rhs != 0 ) { \
|
||||||
|
throw_test_failure_exception(); \
|
||||||
|
} \
|
||||||
|
return { \
|
||||||
|
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
} \
|
||||||
|
template < \
|
||||||
|
typename RhsT, \
|
||||||
|
std::enable_if_t<!Detail::is_##id##_comparable<LhsT, RhsT>::value && \
|
||||||
|
Detail::is_##id##_0_comparable<RhsT>::value && \
|
||||||
|
std::is_same<LhsT, int>::value, \
|
||||||
|
int> = 0> \
|
||||||
|
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||||
|
->BinaryExpr<LhsT, RhsT> { \
|
||||||
|
if ( lhs.m_lhs != 0 ) { \
|
||||||
|
throw_test_failure_exception(); \
|
||||||
|
} \
|
||||||
|
return { static_cast<bool>( 0 op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
|
}
|
||||||
|
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( lt, < )
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( le, <= )
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( gt, > )
|
||||||
|
CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( ge, >= )
|
||||||
|
|
||||||
|
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR
|
||||||
|
|
||||||
template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0>
|
|
||||||
friend auto operator != ( ExprLhs && lhs, RhsT && rhs ) -> BinaryExpr<LhsT, RhsT const&> {
|
|
||||||
return { compareNotEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "!="_sr, rhs };
|
|
||||||
}
|
|
||||||
template<typename RhsT, std::enable_if_t<std::is_arithmetic<RhsT>::value, int> = 0>
|
|
||||||
friend auto operator != ( ExprLhs && lhs, RhsT rhs ) -> BinaryExpr<LhsT, RhsT> {
|
|
||||||
return { compareNotEqual( lhs.m_lhs, rhs ), lhs.m_lhs, "!="_sr, rhs };
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op) \
|
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(op) \
|
||||||
template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0> \
|
template<typename RhsT, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, int> = 0> \
|
||||||
@ -5509,10 +5707,6 @@ namespace Catch {
|
|||||||
return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
|
return { static_cast<bool>(lhs.m_lhs op rhs), lhs.m_lhs, #op##_sr, rhs }; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(<)
|
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(>)
|
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(<=)
|
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(>=)
|
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
|
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(|)
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
|
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(&)
|
||||||
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(^)
|
CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR(^)
|
||||||
@ -5614,7 +5808,7 @@ namespace Catch {
|
|||||||
auto allowThrows() const -> bool;
|
auto allowThrows() const -> bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
|
void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str );
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@ -5753,7 +5947,7 @@ namespace Catch {
|
|||||||
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
|
Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher ); \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
catchAssertionHandler.handleThrowingCallSkipped(); \
|
catchAssertionHandler.handleThrowingCallSkipped(); \
|
||||||
@ -6489,6 +6683,7 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
|
||||||
INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
|
INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
|
||||||
namespace {\
|
namespace {\
|
||||||
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
|
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
|
||||||
@ -6535,6 +6730,7 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
|
||||||
template<typename TestType> static void TestFuncName(); \
|
template<typename TestType> static void TestFuncName(); \
|
||||||
namespace {\
|
namespace {\
|
||||||
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
|
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
|
||||||
@ -6584,6 +6780,7 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
|
||||||
template<typename TestType> static void TestFunc(); \
|
template<typename TestType> static void TestFunc(); \
|
||||||
namespace {\
|
namespace {\
|
||||||
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
|
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
|
||||||
@ -6715,6 +6912,7 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||||
|
CATCH_INTERNAL_SUPPRESS_COMMA_WARNINGS \
|
||||||
template<typename TestType> \
|
template<typename TestType> \
|
||||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
|
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
|
||||||
void test();\
|
void test();\
|
||||||
@ -7114,8 +7312,8 @@ namespace Catch {
|
|||||||
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 3
|
#define CATCH_VERSION_MAJOR 3
|
||||||
#define CATCH_VERSION_MINOR 1
|
#define CATCH_VERSION_MINOR 2
|
||||||
#define CATCH_VERSION_PATCH 1
|
#define CATCH_VERSION_PATCH 0
|
||||||
|
|
||||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
|
||||||
@ -8607,6 +8805,21 @@ namespace Catch {
|
|||||||
#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
|
#endif // CATCH_FLOATING_POINT_HELPERS_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CATCH_GETENV_HPP_INCLUDED
|
||||||
|
#define CATCH_GETENV_HPP_INCLUDED
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
namespace Detail {
|
||||||
|
|
||||||
|
//! Wrapper over `std::getenv` that compiles on UWP (and always returns nullptr there)
|
||||||
|
char const* getEnv(char const* varName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CATCH_GETENV_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#ifndef CATCH_ISTREAM_HPP_INCLUDED
|
#ifndef CATCH_ISTREAM_HPP_INCLUDED
|
||||||
#define CATCH_ISTREAM_HPP_INCLUDED
|
#define CATCH_ISTREAM_HPP_INCLUDED
|
||||||
|
|
||||||
@ -8815,6 +9028,26 @@ namespace Catch {
|
|||||||
#endif // CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
|
#endif // CATCH_OUTPUT_REDIRECT_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CATCH_PARSE_NUMBERS_HPP_INCLUDED
|
||||||
|
#define CATCH_PARSE_NUMBERS_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Catch {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses unsigned int from the input, using provided base
|
||||||
|
*
|
||||||
|
* Effectively a wrapper around std::stoul but with better error checking
|
||||||
|
* e.g. "-1" is rejected, instead of being parsed as UINT_MAX.
|
||||||
|
*/
|
||||||
|
Optional<unsigned int> parseUInt(std::string const& input, int base = 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CATCH_PARSE_NUMBERS_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
|
#ifndef CATCH_REPORTER_REGISTRY_HPP_INCLUDED
|
||||||
#define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
|
#define CATCH_REPORTER_REGISTRY_HPP_INCLUDED
|
||||||
|
|
||||||
@ -9520,7 +9753,6 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
TestSpec parseTestSpec( std::string const& arg );
|
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
|
|
||||||
@ -9903,13 +10135,11 @@ namespace Catch {
|
|||||||
class MatchExpr : public ITransientExpression {
|
class MatchExpr : public ITransientExpression {
|
||||||
ArgT && m_arg;
|
ArgT && m_arg;
|
||||||
MatcherT const& m_matcher;
|
MatcherT const& m_matcher;
|
||||||
StringRef m_matcherString;
|
|
||||||
public:
|
public:
|
||||||
MatchExpr( ArgT && arg, MatcherT const& matcher, StringRef matcherString )
|
MatchExpr( ArgT && arg, MatcherT const& matcher )
|
||||||
: ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose
|
: ITransientExpression{ true, matcher.match( arg ) }, // not forwarding arg here on purpose
|
||||||
m_arg( CATCH_FORWARD(arg) ),
|
m_arg( CATCH_FORWARD(arg) ),
|
||||||
m_matcher( matcher ),
|
m_matcher( matcher )
|
||||||
m_matcherString( matcherString )
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void streamReconstructedExpression( std::ostream& os ) const override {
|
void streamReconstructedExpression( std::ostream& os ) const override {
|
||||||
@ -9926,11 +10156,11 @@ namespace Catch {
|
|||||||
|
|
||||||
using StringMatcher = Matchers::MatcherBase<std::string>;
|
using StringMatcher = Matchers::MatcherBase<std::string>;
|
||||||
|
|
||||||
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString );
|
void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher );
|
||||||
|
|
||||||
template<typename ArgT, typename MatcherT>
|
template<typename ArgT, typename MatcherT>
|
||||||
auto makeMatchExpr( ArgT && arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr<ArgT, MatcherT> {
|
auto makeMatchExpr( ArgT && arg, MatcherT const& matcher ) -> MatchExpr<ArgT, MatcherT> {
|
||||||
return MatchExpr<ArgT, MatcherT>( CATCH_FORWARD(arg), matcher, matcherString );
|
return MatchExpr<ArgT, MatcherT>( CATCH_FORWARD(arg), matcher );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Catch
|
} // namespace Catch
|
||||||
@ -9941,7 +10171,7 @@ namespace Catch {
|
|||||||
do { \
|
do { \
|
||||||
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
|
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
|
||||||
INTERNAL_CATCH_TRY { \
|
INTERNAL_CATCH_TRY { \
|
||||||
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
|
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher ) ); \
|
||||||
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
||||||
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
||||||
} while( false )
|
} while( false )
|
||||||
@ -9957,7 +10187,7 @@ namespace Catch {
|
|||||||
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
|
||||||
} \
|
} \
|
||||||
catch( exceptionType const& ex ) { \
|
catch( exceptionType const& ex ) { \
|
||||||
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
|
catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher ) ); \
|
||||||
} \
|
} \
|
||||||
catch( ... ) { \
|
catch( ... ) { \
|
||||||
catchAssertionHandler.handleUnexpectedInflightException(); \
|
catchAssertionHandler.handleUnexpectedInflightException(); \
|
||||||
@ -10217,7 +10447,7 @@ namespace Matchers {
|
|||||||
MatcherGenericBase() = default;
|
MatcherGenericBase() = default;
|
||||||
~MatcherGenericBase() override; // = default;
|
~MatcherGenericBase() override; // = default;
|
||||||
|
|
||||||
MatcherGenericBase(MatcherGenericBase&) = default;
|
MatcherGenericBase(MatcherGenericBase const&) = default;
|
||||||
MatcherGenericBase(MatcherGenericBase&&) = default;
|
MatcherGenericBase(MatcherGenericBase&&) = default;
|
||||||
|
|
||||||
MatcherGenericBase& operator=(MatcherGenericBase const&) = delete;
|
MatcherGenericBase& operator=(MatcherGenericBase const&) = delete;
|
||||||
@ -11480,7 +11710,6 @@ namespace Catch {
|
|||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
// Fwd decls
|
// Fwd decls
|
||||||
struct SummaryColumn;
|
|
||||||
class TablePrinter;
|
class TablePrinter;
|
||||||
|
|
||||||
class ConsoleReporter final : public StreamingReporterBase {
|
class ConsoleReporter final : public StreamingReporterBase {
|
||||||
@ -11524,12 +11753,7 @@ namespace Catch {
|
|||||||
// subsequent lines
|
// subsequent lines
|
||||||
void printHeaderString(std::string const& _string, std::size_t indent = 0);
|
void printHeaderString(std::string const& _string, std::size_t indent = 0);
|
||||||
|
|
||||||
|
|
||||||
void printTotals(Totals const& totals);
|
|
||||||
void printSummaryRow(StringRef label, std::vector<SummaryColumn> const& cols, std::size_t row);
|
|
||||||
|
|
||||||
void printTotalsDivider(Totals const& totals);
|
void printTotalsDivider(Totals const& totals);
|
||||||
void printSummaryDivider();
|
|
||||||
|
|
||||||
bool m_headerPrinted = false;
|
bool m_headerPrinted = false;
|
||||||
bool m_testRunInfoPrinted = false;
|
bool m_testRunInfoPrinted = false;
|
||||||
@ -11809,6 +12033,15 @@ namespace Catch {
|
|||||||
bool isFiltered,
|
bool isFiltered,
|
||||||
Verbosity verbosity );
|
Verbosity verbosity );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints test run totals to the provided stream in user-friendly format
|
||||||
|
*
|
||||||
|
* Used by the console and compact reporters.
|
||||||
|
*/
|
||||||
|
void printTestRunTotals( std::ostream& stream,
|
||||||
|
ColourImpl& streamColour,
|
||||||
|
Totals const& totals );
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED
|
#endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
project(
|
project(
|
||||||
'catch2',
|
'catch2',
|
||||||
'cpp',
|
'cpp',
|
||||||
version: '3.1.1', # CML version placeholder, don't delete
|
version: '3.2.0', # CML version placeholder, don't delete
|
||||||
license: 'BSL-1.0',
|
license: 'BSL-1.0',
|
||||||
meson_version: '>=0.50.0',
|
meson_version: '>=0.50.0',
|
||||||
)
|
)
|
||||||
|
@ -36,7 +36,7 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Version const& libraryVersion() {
|
Version const& libraryVersion() {
|
||||||
static Version version( 3, 1, 1, "", 0 );
|
static Version version( 3, 2, 0, "", 0 );
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
#define CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
|
||||||
#define CATCH_VERSION_MAJOR 3
|
#define CATCH_VERSION_MAJOR 3
|
||||||
#define CATCH_VERSION_MINOR 1
|
#define CATCH_VERSION_MINOR 2
|
||||||
#define CATCH_VERSION_PATCH 1
|
#define CATCH_VERSION_PATCH 0
|
||||||
|
|
||||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||||
|
Loading…
Reference in New Issue
Block a user