mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-16 18:52:25 +01:00
Merge branch 'devel' into devel
This commit is contained in:
commit
d1de503150
8
.github/workflows/linux-other-builds.yml
vendored
8
.github/workflows/linux-other-builds.yml
vendored
@ -29,13 +29,13 @@ jobs:
|
||||
build_type: Debug
|
||||
std: 14
|
||||
other_pkgs: g++-7
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
- cxx: g++-7
|
||||
build_description: Extras + Examples
|
||||
build_type: Release
|
||||
std: 14
|
||||
other_pkgs: g++-7
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
|
||||
# Extras and examples with Clang-10
|
||||
- cxx: clang++-10
|
||||
@ -43,13 +43,13 @@ jobs:
|
||||
build_type: Debug
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
- cxx: clang++-10
|
||||
build_description: Extras + Examples
|
||||
build_type: Release
|
||||
std: 17
|
||||
other_pkgs: clang-10
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON
|
||||
cmake_configurations: -DCATCH_BUILD_EXTRA_TESTS=ON -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
|
||||
# Configure tests with Clang-10
|
||||
- cxx: clang++-10
|
||||
|
@ -43,12 +43,14 @@ expand_template(
|
||||
"#cmakedefine CATCH_CONFIG_NO_GLOBAL_NEXTAFTER": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_POSIX_SIGNALS": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_USE_ASYNC": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_WCHAR": "",
|
||||
"#cmakedefine CATCH_CONFIG_NO_WINDOWS_SEH": "",
|
||||
"#cmakedefine CATCH_CONFIG_NOSTDOUT": "",
|
||||
"#cmakedefine CATCH_CONFIG_POSIX_SIGNALS": "",
|
||||
"#cmakedefine CATCH_CONFIG_PREFIX_ALL": "",
|
||||
"#cmakedefine CATCH_CONFIG_SHARED_LIBRARY": "",
|
||||
"#cmakedefine CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||
"#cmakedefine CATCH_CONFIG_USE_ASYNC": "",
|
||||
"#cmakedefine CATCH_CONFIG_WCHAR": "",
|
||||
"#cmakedefine CATCH_CONFIG_WINDOWS_CRTDBG": "",
|
||||
|
@ -41,6 +41,7 @@ set(_OverridableOptions
|
||||
"WCHAR"
|
||||
"WINDOWS_SEH"
|
||||
"GETENV"
|
||||
"EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT"
|
||||
)
|
||||
|
||||
foreach(OptionName ${_OverridableOptions})
|
||||
|
@ -21,6 +21,7 @@ cmake_dependent_option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io"
|
||||
cmake_dependent_option(CATCH_ENABLE_WERROR "Enables Werror during build" ON "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_BUILD_SURROGATES "Enable generating and building surrogate TUs for the main headers" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_CONFIGURE_TESTS "Enable CMake configuration tests. WARNING: VERY EXPENSIVE" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
cmake_dependent_option(CATCH_ENABLE_CMAKE_HELPER_TESTS "Enable CMake helper tests. WARNING: VERY EXPENSIVE" OFF "CATCH_DEVELOPMENT_BUILD" OFF)
|
||||
|
||||
|
||||
# Catch2's build breaks if done in-tree. You probably should not build
|
||||
|
@ -18,7 +18,8 @@
|
||||
"CATCH_BUILD_EXAMPLES": "ON",
|
||||
"CATCH_BUILD_EXTRA_TESTS": "ON",
|
||||
"CATCH_BUILD_SURROGATES": "ON",
|
||||
"CATCH_ENABLE_CONFIGURE_TESTS": "ON"
|
||||
"CATCH_ENABLE_CONFIGURE_TESTS": "ON",
|
||||
"CATCH_ENABLE_CMAKE_HELPER_TESTS": "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -4,10 +4,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
|
||||
sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
[Enabling stringification](#enabling-stringification)<br>
|
||||
[Disabling exceptions](#disabling-exceptions)<br>
|
||||
[Overriding Catch's debug break (`-b`)](#overriding-catchs-debug-break--b)<br>
|
||||
[Static analysis support](#static-analysis-support)<br>
|
||||
|
||||
Catch2 is designed to "just work" as much as possible, and most of the
|
||||
configuration options below are changed automatically during compilation,
|
||||
|
@ -221,3 +221,21 @@ For full example of implementing your own generator, look into Catch2's
|
||||
examples, specifically
|
||||
[Generators: Create your own generator](../examples/300-Gen-OwnGenerator.cpp).
|
||||
|
||||
|
||||
### Handling empty generators
|
||||
|
||||
The generator interface assumes that a generator always has at least one
|
||||
element. This is not always true, e.g. if the generator depends on an external
|
||||
datafile, the file might be missing.
|
||||
|
||||
There are two ways to handle this, depending on whether you want this
|
||||
to be an error or not.
|
||||
|
||||
* If empty generator **is** an error, throw an exception in constructor.
|
||||
* If empty generator **is not** an error, use the [`SKIP`](skipping-passing-failing.md#skipping-test-cases-at-runtime) in constructor.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@ -52,7 +52,7 @@ its machine-readable XML output to file `result-junit.xml`, and the
|
||||
uses ANSI colour codes for colouring the output.
|
||||
|
||||
Using multiple reporters (or one reporter and one-or-more [event
|
||||
listeners](event-listener.md#top)) can have surprisingly complex semantics
|
||||
listeners](event-listeners.md#top)) can have surprisingly complex semantics
|
||||
when using customization points provided to reporters by Catch2, namely
|
||||
capturing stdout/stderr from test cases.
|
||||
|
||||
|
@ -84,6 +84,12 @@ exit code, same as it does if no test cases have run. This behaviour can
|
||||
be overridden using the [--allow-running-no-tests](command-line.md#no-tests-override)
|
||||
flag.
|
||||
|
||||
### `SKIP` inside generators
|
||||
|
||||
You can also use the `SKIP` macro inside generator's constructor to handle
|
||||
cases where the generator is empty, but you do not want to fail the test
|
||||
case.
|
||||
|
||||
|
||||
## Passing and failing test cases
|
||||
|
||||
|
@ -74,6 +74,10 @@ function(catch_discover_tests_impl)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Make sure to escape ; (semicolons) in test names first, because
|
||||
# that'd break the foreach loop for "Parse output" later and create
|
||||
# wrongly splitted and thus failing test cases (false positives)
|
||||
string(REPLACE ";" "\;" output "${output}")
|
||||
string(REPLACE "\n" ";" output "${output}")
|
||||
|
||||
# Prepare reporter
|
||||
@ -119,15 +123,16 @@ function(catch_discover_tests_impl)
|
||||
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
set(test ${line})
|
||||
set(test "${line}")
|
||||
# Escape characters in test case names that would be parsed by Catch2
|
||||
set(test_name ${test})
|
||||
foreach(char , [ ])
|
||||
string(REPLACE ${char} "\\${char}" test_name ${test_name})
|
||||
# Note that the \ escaping must happen FIRST! Do not change the order.
|
||||
set(test_name "${test}")
|
||||
foreach(char \\ , [ ])
|
||||
string(REPLACE ${char} "\\${char}" test_name "${test_name}")
|
||||
endforeach(char)
|
||||
# ...add output dir
|
||||
if(output_dir)
|
||||
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
|
||||
string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean "${test_name}")
|
||||
set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
|
||||
endif()
|
||||
|
||||
|
@ -73,6 +73,7 @@ set(IMPL_HEADERS
|
||||
${SOURCES_DIR}/internal/catch_compiler_capabilities.hpp
|
||||
${SOURCES_DIR}/internal/catch_config_android_logwrite.hpp
|
||||
${SOURCES_DIR}/internal/catch_config_counter.hpp
|
||||
${SOURCES_DIR}/internal/catch_config_static_analysis_support.hpp
|
||||
${SOURCES_DIR}/internal/catch_config_uncaught_exceptions.hpp
|
||||
${SOURCES_DIR}/internal/catch_config_wchar.hpp
|
||||
${SOURCES_DIR}/internal/catch_console_colour.hpp
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||
#include <catch2/internal/catch_config_android_logwrite.hpp>
|
||||
#include <catch2/internal/catch_config_counter.hpp>
|
||||
#include <catch2/internal/catch_config_static_analysis_support.hpp>
|
||||
#include <catch2/internal/catch_config_uncaught_exceptions.hpp>
|
||||
#include <catch2/internal/catch_config_wchar.hpp>
|
||||
#include <catch2/internal/catch_console_colour.hpp>
|
||||
|
@ -169,6 +169,15 @@
|
||||
#endif
|
||||
|
||||
|
||||
#cmakedefine CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT ) && \
|
||||
defined( CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )
|
||||
# error Cannot force STATIC_ANALYSIS_SUPPORT to both ON and OFF
|
||||
#endif
|
||||
|
||||
|
||||
// ------
|
||||
// Simple toggle defines
|
||||
// their value is never used and they cannot be overridden
|
||||
|
34
src/catch2/internal/catch_config_static_analysis_support.hpp
Normal file
34
src/catch2/internal/catch_config_static_analysis_support.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
/** \file
|
||||
* Wrapper for the STATIC_ANALYSIS_SUPPORT configuration option
|
||||
*
|
||||
* Some of Catch2's macros can be defined differently to work better with
|
||||
* static analysis tools, like clang-tidy or coverity.
|
||||
* Currently the main use case is to show that `SECTION`s are executed
|
||||
* exclusively, and not all in one run of a `TEST_CASE`.
|
||||
*/
|
||||
|
||||
#ifndef CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
|
||||
#define CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_user_config.hpp>
|
||||
|
||||
#if defined(__clang_analyzer__) || defined(__COVERITY__)
|
||||
#define CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT
|
||||
#endif
|
||||
|
||||
#if defined( CATCH_INTERNAL_CONFIG_STATIC_ANALYSIS_SUPPORT ) && \
|
||||
!defined( CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT ) && \
|
||||
!defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )
|
||||
# define CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CATCH_CONFIG_STATIC_ANALYSIS_SUPPORT_HPP_INCLUDED
|
@ -9,6 +9,7 @@
|
||||
#define CATCH_SECTION_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||
#include <catch2/internal/catch_config_static_analysis_support.hpp>
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/catch_section_info.hpp>
|
||||
#include <catch2/catch_timer.hpp>
|
||||
@ -38,16 +39,62 @@ namespace Catch {
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
|
||||
# define INTERNAL_CATCH_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
if ( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( \
|
||||
catch_internal_Section ) = \
|
||||
Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
# define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
if ( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( \
|
||||
catch_internal_Section ) = \
|
||||
Catch::SectionInfo( \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
( Catch::ReusableStringStream() << __VA_ARGS__ ) \
|
||||
.str() ) ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
#else
|
||||
|
||||
// These section definitions imply that at most one section at one level
|
||||
// will be intered (because only one section's __LINE__ can be equal to
|
||||
// the dummy `catchInternalSectionHint` variable from `TEST_CASE`).
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
// Intentionally without linkage, as it should only be used as a dummy
|
||||
// symbol for static analysis.
|
||||
int GetNewSectionHint();
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
|
||||
# define INTERNAL_CATCH_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
# define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
#endif
|
||||
|
||||
#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
#endif // CATCH_SECTION_HPP_INCLUDED
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||
#define CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||
|
||||
#include <catch2/internal/catch_config_static_analysis_support.hpp>
|
||||
#include <catch2/internal/catch_source_line_info.hpp>
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/interfaces/catch_interfaces_test_invoker.hpp>
|
||||
@ -72,6 +73,9 @@ struct AutoReg : Detail::NonCopyable {
|
||||
void TestName::test()
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||
static void TestName(); \
|
||||
@ -84,19 +88,40 @@ struct AutoReg : Detail::NonCopyable {
|
||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
namespace { \
|
||||
const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
|
||||
Catch::makeTestInvoker( &QualifiedMethod ), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
"&" #QualifiedMethod##_catch_sr, \
|
||||
Catch::NameAndTags{ __VA_ARGS__ } ); \
|
||||
} /* NOLINT */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
|
||||
|
||||
// Dummy registrator for the dumy test case macros
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
struct DummyUse {
|
||||
DummyUse( void ( * )( int ) );
|
||||
};
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
// Note that both the presence of the argument and its exact name are
|
||||
// necessary for the section support.
|
||||
|
||||
// We provide a shadowed variable so that a `SECTION` inside non-`TEST_CASE`
|
||||
// tests can compile. The redefined `TEST_CASE` shadows this with param.
|
||||
static int catchInternalSectionHint = 0;
|
||||
|
||||
# define INTERNAL_CATCH_TESTCASE2( fname ) \
|
||||
static void fname( int ); \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
static const Catch::Detail::DummyUse INTERNAL_CATCH_UNIQUE_NAME( \
|
||||
dummyUser )( &fname ); \
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
static void fname( [[maybe_unused]] int catchInternalSectionHint ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
# define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( dummyFunction ) )
|
||||
|
||||
|
||||
#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||
@ -118,6 +143,22 @@ struct AutoReg : Detail::NonCopyable {
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
||||
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||
namespace { \
|
||||
const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
|
||||
Catch::makeTestInvoker( &QualifiedMethod ), \
|
||||
CATCH_INTERNAL_LINEINFO, \
|
||||
"&" #QualifiedMethod##_catch_sr, \
|
||||
Catch::NameAndTags{ __VA_ARGS__ } ); \
|
||||
} /* NOLINT */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||
do { \
|
||||
|
@ -78,6 +78,7 @@ internal_headers = [
|
||||
'internal/catch_compiler_capabilities.hpp',
|
||||
'internal/catch_config_android_logwrite.hpp',
|
||||
'internal/catch_config_counter.hpp',
|
||||
'internal/catch_config_static_analysis_support.hpp',
|
||||
'internal/catch_config_uncaught_exceptions.hpp',
|
||||
'internal/catch_config_wchar.hpp',
|
||||
'internal/catch_console_colour.hpp',
|
||||
|
@ -622,6 +622,18 @@ if (CATCH_ENABLE_CONFIGURE_TESTS)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (CATCH_ENABLE_CMAKE_HELPER_TESTS)
|
||||
add_test(NAME "CMakeHelper::DiscoverTests"
|
||||
COMMAND
|
||||
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/TestScripts/DiscoverTests/VerifyRegistration.py" "${CATCH_DIR}" "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
set_tests_properties("CMakeHelper::DiscoverTests"
|
||||
PROPERTIES
|
||||
COST 240
|
||||
LABELS "uses-python"
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach (reporterName # "Automake" - the simple .trs format does not support any kind of comments/metadata
|
||||
"compact"
|
||||
"console"
|
||||
|
@ -130,6 +130,7 @@ Nor would this
|
||||
:test-result: FAIL Custom std-exceptions can be custom translated
|
||||
:test-result: PASS Default scale is invisible to comparison
|
||||
:test-result: PASS Directly creating an EnumInfo
|
||||
:test-result: SKIP Empty generators can SKIP in constructor
|
||||
:test-result: PASS Empty stream name opens cout stream
|
||||
:test-result: FAIL EndsWith string matcher
|
||||
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
|
||||
|
@ -128,6 +128,7 @@
|
||||
:test-result: FAIL Custom std-exceptions can be custom translated
|
||||
:test-result: PASS Default scale is invisible to comparison
|
||||
:test-result: PASS Directly creating an EnumInfo
|
||||
:test-result: SKIP Empty generators can SKIP in constructor
|
||||
:test-result: PASS Empty stream name opens cout stream
|
||||
:test-result: FAIL EndsWith string matcher
|
||||
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
|
||||
|
@ -520,6 +520,7 @@ ToString.tests.cpp:<line number>: passed: enumInfo->lookup(1) == "Value2" for: V
|
||||
ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **}
|
||||
==
|
||||
"{** unexpected enum value **}"
|
||||
Skip.tests.cpp:<line number>: skipped: 'This generator is empty'
|
||||
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "" )->isConsole() for: true
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive)
|
||||
@ -2537,7 +2538,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: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
test cases: 409 | 308 passed | 84 failed | 6 skipped | 11 failed as expected
|
||||
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
||||
|
@ -518,6 +518,7 @@ ToString.tests.cpp:<line number>: passed: enumInfo->lookup(1) == "Value2" for: V
|
||||
ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **}
|
||||
==
|
||||
"{** unexpected enum value **}"
|
||||
Skip.tests.cpp:<line number>: skipped: 'This generator is empty'
|
||||
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "" )->isConsole() for: true
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring"
|
||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive)
|
||||
@ -2526,7 +2527,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: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
test cases: 409 | 308 passed | 84 failed | 6 skipped | 11 failed as expected
|
||||
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
||||
|
@ -383,6 +383,16 @@ Exception.tests.cpp:<line number>: FAILED:
|
||||
due to unexpected exception with message:
|
||||
custom std exception
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Empty generators can SKIP in constructor
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
This generator is empty
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EndsWith string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
@ -1533,6 +1543,6 @@ due to unexpected exception with message:
|
||||
Why would you throw a std::string?
|
||||
|
||||
===============================================================================
|
||||
test cases: 408 | 322 passed | 69 failed | 6 skipped | 11 failed as expected
|
||||
test cases: 409 | 322 passed | 69 failed | 7 skipped | 11 failed as expected
|
||||
assertions: 2208 | 2048 passed | 128 failed | 32 failed as expected
|
||||
|
||||
|
@ -3956,6 +3956,16 @@ with expansion:
|
||||
==
|
||||
"{** unexpected enum value **}"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Empty generators can SKIP in constructor
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
This generator is empty
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Empty stream name opens cout stream
|
||||
-------------------------------------------------------------------------------
|
||||
@ -18222,6 +18232,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
test cases: 409 | 308 passed | 84 failed | 6 skipped | 11 failed as expected
|
||||
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
@ -3954,6 +3954,16 @@ with expansion:
|
||||
==
|
||||
"{** unexpected enum value **}"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Empty generators can SKIP in constructor
|
||||
-------------------------------------------------------------------------------
|
||||
Skip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Skip.tests.cpp:<line number>: SKIPPED:
|
||||
explicitly with message:
|
||||
This generator is empty
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Empty stream name opens cout stream
|
||||
-------------------------------------------------------------------------------
|
||||
@ -18211,6 +18221,6 @@ Misc.tests.cpp:<line number>
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 408 | 308 passed | 84 failed | 5 skipped | 11 failed as expected
|
||||
test cases: 409 | 308 passed | 84 failed | 6 skipped | 11 failed as expected
|
||||
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2236" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="17" failures="128" skipped="12" tests="2237" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<properties>
|
||||
<property name="random-seed" value="1"/>
|
||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||
@ -462,6 +462,13 @@ at Exception.tests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Empty generators can SKIP in constructor" time="{duration}" status="run">
|
||||
<skipped type="SKIP">
|
||||
SKIPPED
|
||||
This generator is empty
|
||||
at Skip.tests.cpp:<line number>
|
||||
</skipped>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Empty stream name opens cout stream" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}" status="run">
|
||||
<failure message="testStringForMatching(), EndsWith( "Substring" )" type="CHECK_THAT">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites>
|
||||
<testsuite name="<exe-name>" errors="17" failures="128" skipped="11" tests="2236" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="17" failures="128" skipped="12" tests="2237" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<properties>
|
||||
<property name="random-seed" value="1"/>
|
||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||
@ -461,6 +461,13 @@ at Exception.tests.cpp:<line number>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Directly creating an EnumInfo" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="Empty generators can SKIP in constructor" time="{duration}" status="run">
|
||||
<skipped type="SKIP">
|
||||
SKIPPED
|
||||
This generator is empty
|
||||
at Skip.tests.cpp:<line number>
|
||||
</skipped>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Empty stream name opens cout stream" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="EndsWith string matcher" time="{duration}" status="run">
|
||||
<failure message="testStringForMatching(), EndsWith( "Substring" )" type="CHECK_THAT">
|
||||
|
@ -1870,6 +1870,13 @@ at Misc.tests.cpp:<line number>
|
||||
<testCase name="xmlentitycheck/encoded chars: these should all be encoded: &&&"""<<<&"<<&"" duration="{duration}"/>
|
||||
</file>
|
||||
<file path="tests/<exe-name>/UsageTests/Skip.tests.cpp">
|
||||
<testCase name="Empty generators can SKIP in constructor" duration="{duration}">
|
||||
<skipped message="SKIP()">
|
||||
SKIPPED
|
||||
This generator is empty
|
||||
at Skip.tests.cpp:<line number>
|
||||
</skipped>
|
||||
</testCase>
|
||||
<testCase name="a succeeding test can still be skipped" duration="{duration}">
|
||||
<skipped message="SKIP()">
|
||||
SKIPPED
|
||||
|
@ -1869,6 +1869,13 @@ at Misc.tests.cpp:<line number>
|
||||
<testCase name="xmlentitycheck/encoded chars: these should all be encoded: &&&"""<<<&"<<&"" duration="{duration}"/>
|
||||
</file>
|
||||
<file path="tests/<exe-name>/UsageTests/Skip.tests.cpp">
|
||||
<testCase name="Empty generators can SKIP in constructor" duration="{duration}">
|
||||
<skipped message="SKIP()">
|
||||
SKIPPED
|
||||
This generator is empty
|
||||
at Skip.tests.cpp:<line number>
|
||||
</skipped>
|
||||
</testCase>
|
||||
<testCase name="a succeeding test can still be skipped" duration="{duration}">
|
||||
<skipped message="SKIP()">
|
||||
SKIPPED
|
||||
|
@ -984,6 +984,8 @@ ok {test-number} - enumInfo->lookup(0) == "Value1" for: Value1 == "Value1"
|
||||
ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
|
||||
# Directly creating an EnumInfo
|
||||
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
|
||||
# Empty generators can SKIP in constructor
|
||||
ok {test-number} - # SKIP 'This generator is empty'
|
||||
# Empty stream name opens cout stream
|
||||
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
||||
# EndsWith string matcher
|
||||
@ -4475,5 +4477,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..2236
|
||||
1..2237
|
||||
|
||||
|
@ -982,6 +982,8 @@ ok {test-number} - enumInfo->lookup(0) == "Value1" for: Value1 == "Value1"
|
||||
ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
|
||||
# Directly creating an EnumInfo
|
||||
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
|
||||
# Empty generators can SKIP in constructor
|
||||
ok {test-number} - # SKIP 'This generator is empty'
|
||||
# Empty stream name opens cout stream
|
||||
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
||||
# EndsWith string matcher
|
||||
@ -4464,5 +4466,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
||||
ok {test-number} -
|
||||
# xmlentitycheck
|
||||
ok {test-number} -
|
||||
1..2236
|
||||
1..2237
|
||||
|
||||
|
@ -299,6 +299,9 @@
|
||||
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
||||
##teamcity[testStarted name='Directly creating an EnumInfo']
|
||||
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
|
||||
##teamcity[testStarted name='Empty generators can SKIP in constructor']
|
||||
##teamcity[testIgnored name='Empty generators can SKIP in constructor' message='Skip.tests.cpp:<line number>|n...............................................................................|n|nSkip.tests.cpp:<line number>|nexplicit skip with message:|n "This generator is empty"']
|
||||
##teamcity[testFinished name='Empty generators can SKIP in constructor' duration="{duration}"]
|
||||
##teamcity[testStarted name='Empty stream name opens cout stream']
|
||||
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
||||
##teamcity[testStarted name='EndsWith string matcher']
|
||||
|
@ -299,6 +299,9 @@
|
||||
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
||||
##teamcity[testStarted name='Directly creating an EnumInfo']
|
||||
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
|
||||
##teamcity[testStarted name='Empty generators can SKIP in constructor']
|
||||
##teamcity[testIgnored name='Empty generators can SKIP in constructor' message='Skip.tests.cpp:<line number>|n...............................................................................|n|nSkip.tests.cpp:<line number>|nexplicit skip with message:|n "This generator is empty"']
|
||||
##teamcity[testFinished name='Empty generators can SKIP in constructor' duration="{duration}"]
|
||||
##teamcity[testStarted name='Empty stream name opens cout stream']
|
||||
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
||||
##teamcity[testStarted name='EndsWith string matcher']
|
||||
|
@ -4364,6 +4364,12 @@ C
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
<TestCase name="Empty generators can SKIP in constructor" tags="[skipping]" filename="tests/<exe-name>/UsageTests/Skip.tests.cpp" >
|
||||
<Skip filename="tests/<exe-name>/UsageTests/Skip.tests.cpp" >
|
||||
This generator is empty
|
||||
</Skip>
|
||||
<OverallResult success="true" skips="1"/>
|
||||
</TestCase>
|
||||
<TestCase name="Empty stream name opens cout stream" tags="[streams]" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||
<Original>
|
||||
@ -21192,6 +21198,6 @@ b1!
|
||||
</Section>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
|
||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
|
||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="12"/>
|
||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="6"/>
|
||||
</Catch2TestRun>
|
||||
|
@ -4364,6 +4364,12 @@ C
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
<TestCase name="Empty generators can SKIP in constructor" tags="[skipping]" filename="tests/<exe-name>/UsageTests/Skip.tests.cpp" >
|
||||
<Skip filename="tests/<exe-name>/UsageTests/Skip.tests.cpp" >
|
||||
This generator is empty
|
||||
</Skip>
|
||||
<OverallResult success="true" skips="1"/>
|
||||
</TestCase>
|
||||
<TestCase name="Empty stream name opens cout stream" tags="[streams]" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||
<Original>
|
||||
@ -21191,6 +21197,6 @@ b1!
|
||||
</Section>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
|
||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
|
||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="12"/>
|
||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="6"/>
|
||||
</Catch2TestRun>
|
||||
|
@ -95,8 +95,8 @@ namespace {
|
||||
MoveChecker() = default;
|
||||
MoveChecker( MoveChecker const& rhs ) = default;
|
||||
MoveChecker& operator=( MoveChecker const& rhs ) = default;
|
||||
MoveChecker( MoveChecker&& rhs ) { rhs.has_moved = true; }
|
||||
MoveChecker& operator=( MoveChecker&& rhs ) {
|
||||
MoveChecker( MoveChecker&& rhs ) noexcept { rhs.has_moved = true; }
|
||||
MoveChecker& operator=( MoveChecker&& rhs ) noexcept {
|
||||
rhs.has_moved = true;
|
||||
return *this;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ namespace {
|
||||
std::vector<std::string>& recorder,
|
||||
Catch::IConfig const* config ):
|
||||
EventListenerBase( config ),
|
||||
m_witness( witness ),
|
||||
m_witness( CATCH_MOVE(witness) ),
|
||||
m_recorder( recorder )
|
||||
{}
|
||||
|
||||
@ -181,7 +181,7 @@ namespace {
|
||||
std::vector<std::string>& recorder,
|
||||
Catch::ReporterConfig&& config ):
|
||||
StreamingReporterBase( CATCH_MOVE(config) ),
|
||||
m_witness( witness ),
|
||||
m_witness( CATCH_MOVE(witness) ),
|
||||
m_recorder( recorder )
|
||||
{}
|
||||
|
||||
|
@ -261,6 +261,10 @@ TEST_CASE("Copy and then generate a range", "[generators]") {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined( __clang__ )
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
TEST_CASE("#1913 - GENERATE inside a for loop should not keep recreating the generator", "[regression][generators]") {
|
||||
static int counter = 0;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@ -305,9 +309,5 @@ TEST_CASE( "#2615 - Throwing in constructor generator fails test case but does n
|
||||
// this should fail the test case, but not abort the application
|
||||
auto sample = GENERATE( make_test_generator() );
|
||||
// this assertion shouldn't trigger
|
||||
REQUIRE( sample == 0U );
|
||||
REQUIRE( sample == 0 );
|
||||
}
|
||||
|
||||
#if defined( __clang__ )
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
@ -890,7 +890,7 @@ struct MatcherA : Catch::Matchers::MatcherGenericBase {
|
||||
return "equals: (int) 1 or (string) \"1\"";
|
||||
}
|
||||
bool match( int i ) const { return i == 1; }
|
||||
bool match( std::string s ) const { return s == "1"; }
|
||||
bool match( std::string const& s ) const { return s == "1"; }
|
||||
};
|
||||
|
||||
struct MatcherB : Catch::Matchers::MatcherGenericBase {
|
||||
|
@ -71,3 +71,30 @@ TEST_CASE( "failing for some generator values causes entire test case to fail",
|
||||
FAIL();
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class test_skip_generator : public Catch::Generators::IGenerator<int> {
|
||||
public:
|
||||
explicit test_skip_generator() { SKIP( "This generator is empty" ); }
|
||||
|
||||
auto get() const -> int const& override {
|
||||
static constexpr int value = 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
auto next() -> bool override { return false; }
|
||||
};
|
||||
|
||||
static auto make_test_skip_generator()
|
||||
-> Catch::Generators::GeneratorWrapper<int> {
|
||||
return { new test_skip_generator() };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE( "Empty generators can SKIP in constructor", "[skipping]" ) {
|
||||
// The generator signals emptiness with `SKIP`
|
||||
auto sample = GENERATE( make_test_skip_generator() );
|
||||
// This assertion would fail, but shouldn't trigger
|
||||
REQUIRE( sample == 0 );
|
||||
}
|
||||
|
16
tests/TestScripts/DiscoverTests/CMakeLists.txt
Normal file
16
tests/TestScripts/DiscoverTests/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(discover-tests-test
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
add_executable(tests
|
||||
register-tests.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(${CATCH2_PATH} catch2-build)
|
||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
|
||||
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
catch_discover_tests(tests)
|
123
tests/TestScripts/DiscoverTests/VerifyRegistration.py
Normal file
123
tests/TestScripts/DiscoverTests/VerifyRegistration.py
Normal file
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright Catch2 Authors
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE.txt or copy at
|
||||
# https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def build_project(sources_dir, output_base_path, catch2_path):
|
||||
build_dir = os.path.join(output_base_path, 'ctest-registration-test')
|
||||
config_cmd = ['cmake',
|
||||
'-B', build_dir,
|
||||
'-S', sources_dir,
|
||||
f'-DCATCH2_PATH={catch2_path}',
|
||||
'-DCMAKE_BUILD_TYPE=Debug']
|
||||
|
||||
build_cmd = ['cmake',
|
||||
'--build', build_dir,
|
||||
'--config', 'Debug']
|
||||
|
||||
try:
|
||||
subprocess.run(config_cmd,
|
||||
capture_output = True,
|
||||
check = True,
|
||||
text = True)
|
||||
subprocess.run(build_cmd,
|
||||
capture_output = True,
|
||||
check = True,
|
||||
text = True)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print('Error when building the test project')
|
||||
print(f'cmd: {err.cmd}')
|
||||
print(f'stderr: {err.stderr}')
|
||||
print(f'stdout: {err.stdout}')
|
||||
exit(3)
|
||||
|
||||
return build_dir
|
||||
|
||||
|
||||
|
||||
def get_test_names(build_path):
|
||||
# For now we assume that Windows builds are done using MSBuild under
|
||||
# Debug configuration. This means that we need to add "Debug" folder
|
||||
# to the path when constructing it. On Linux, we don't add anything.
|
||||
config_path = "Debug" if os.name == 'nt' else ""
|
||||
full_path = os.path.join(build_path, config_path, 'tests')
|
||||
|
||||
|
||||
cmd = [full_path, '--reporter', 'xml', '--list-tests']
|
||||
result = subprocess.run(cmd,
|
||||
capture_output = True,
|
||||
check = True,
|
||||
text = True)
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
root = ET.fromstring(result.stdout)
|
||||
return [tc.text for tc in root.findall('TestCase/Name')]
|
||||
|
||||
|
||||
def list_ctest_tests(build_path):
|
||||
old_path = os.getcwd()
|
||||
os.chdir(build_path)
|
||||
|
||||
cmd = ['ctest', '-C', 'debug', '--show-only=json-v1']
|
||||
result = subprocess.run(cmd,
|
||||
capture_output = True,
|
||||
check = True,
|
||||
text = True)
|
||||
os.chdir(old_path)
|
||||
|
||||
import json
|
||||
|
||||
ctest_response = json.loads(result.stdout)
|
||||
tests = ctest_response['tests']
|
||||
test_names = []
|
||||
for test in tests:
|
||||
test_command = test['command']
|
||||
# First part of the command is the binary, second is the filter.
|
||||
# If there are less, registration has failed. If there are more,
|
||||
# registration has changed and the script needs updating.
|
||||
assert len(test_command) == 2
|
||||
test_names.append(test_command[1])
|
||||
test_name = test_command[1]
|
||||
|
||||
return test_names
|
||||
|
||||
def escape_catch2_test_name(name):
|
||||
for char in ('\\', ',', '[', ']'):
|
||||
name = name.replace(char, f"\\{char}")
|
||||
return name
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print(f'Usage: {sys.argv[0]} path-to-catch2-cml output-path')
|
||||
exit(2)
|
||||
catch2_path = sys.argv[1]
|
||||
output_base_path = sys.argv[2]
|
||||
sources_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
build_path = build_project(sources_dir, output_base_path, catch2_path)
|
||||
|
||||
catch_test_names = [escape_catch2_test_name(name) for name in get_test_names(build_path)]
|
||||
ctest_test_names = list_ctest_tests(build_path)
|
||||
|
||||
mismatched = 0
|
||||
for catch_test in catch_test_names:
|
||||
if catch_test not in ctest_test_names:
|
||||
print(f"Catch2 test '{catch_test}' not found in CTest")
|
||||
mismatched += 1
|
||||
for ctest_test in ctest_test_names:
|
||||
if ctest_test not in catch_test_names:
|
||||
print(f"CTest test '{ctest_test}' not found in Catch2")
|
||||
mismatched += 1
|
||||
|
||||
if mismatched:
|
||||
print(f"Found {mismatched} mismatched tests catch test names and ctest test commands!")
|
||||
exit(1)
|
12
tests/TestScripts/DiscoverTests/register-tests.cpp
Normal file
12
tests/TestScripts/DiscoverTests/register-tests.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("@Script[C:\\EPM1A]=x;\"SCALA_ZERO:\"", "[script regressions]"){}
|
||||
TEST_CASE("Some test") {}
|
Loading…
Reference in New Issue
Block a user