mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-16 10:42: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
|
build_type: Debug
|
||||||
std: 14
|
std: 14
|
||||||
other_pkgs: g++-7
|
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
|
- cxx: g++-7
|
||||||
build_description: Extras + Examples
|
build_description: Extras + Examples
|
||||||
build_type: Release
|
build_type: Release
|
||||||
std: 14
|
std: 14
|
||||||
other_pkgs: g++-7
|
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
|
# Extras and examples with Clang-10
|
||||||
- cxx: clang++-10
|
- cxx: clang++-10
|
||||||
@ -43,13 +43,13 @@ jobs:
|
|||||||
build_type: Debug
|
build_type: Debug
|
||||||
std: 17
|
std: 17
|
||||||
other_pkgs: clang-10
|
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
|
- cxx: clang++-10
|
||||||
build_description: Extras + Examples
|
build_description: Extras + Examples
|
||||||
build_type: Release
|
build_type: Release
|
||||||
std: 17
|
std: 17
|
||||||
other_pkgs: clang-10
|
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
|
# Configure tests with Clang-10
|
||||||
- cxx: clang++-10
|
- cxx: clang++-10
|
||||||
|
@ -43,12 +43,14 @@ expand_template(
|
|||||||
"#cmakedefine CATCH_CONFIG_NO_GLOBAL_NEXTAFTER": "",
|
"#cmakedefine CATCH_CONFIG_NO_GLOBAL_NEXTAFTER": "",
|
||||||
"#cmakedefine CATCH_CONFIG_NO_POSIX_SIGNALS": "",
|
"#cmakedefine CATCH_CONFIG_NO_POSIX_SIGNALS": "",
|
||||||
"#cmakedefine CATCH_CONFIG_NO_USE_ASYNC": "",
|
"#cmakedefine CATCH_CONFIG_NO_USE_ASYNC": "",
|
||||||
|
"#cmakedefine CATCH_CONFIG_NO_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||||
"#cmakedefine CATCH_CONFIG_NO_WCHAR": "",
|
"#cmakedefine CATCH_CONFIG_NO_WCHAR": "",
|
||||||
"#cmakedefine CATCH_CONFIG_NO_WINDOWS_SEH": "",
|
"#cmakedefine CATCH_CONFIG_NO_WINDOWS_SEH": "",
|
||||||
"#cmakedefine CATCH_CONFIG_NOSTDOUT": "",
|
"#cmakedefine CATCH_CONFIG_NOSTDOUT": "",
|
||||||
"#cmakedefine CATCH_CONFIG_POSIX_SIGNALS": "",
|
"#cmakedefine CATCH_CONFIG_POSIX_SIGNALS": "",
|
||||||
"#cmakedefine CATCH_CONFIG_PREFIX_ALL": "",
|
"#cmakedefine CATCH_CONFIG_PREFIX_ALL": "",
|
||||||
"#cmakedefine CATCH_CONFIG_SHARED_LIBRARY": "",
|
"#cmakedefine CATCH_CONFIG_SHARED_LIBRARY": "",
|
||||||
|
"#cmakedefine CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT": "",
|
||||||
"#cmakedefine CATCH_CONFIG_USE_ASYNC": "",
|
"#cmakedefine CATCH_CONFIG_USE_ASYNC": "",
|
||||||
"#cmakedefine CATCH_CONFIG_WCHAR": "",
|
"#cmakedefine CATCH_CONFIG_WCHAR": "",
|
||||||
"#cmakedefine CATCH_CONFIG_WINDOWS_CRTDBG": "",
|
"#cmakedefine CATCH_CONFIG_WINDOWS_CRTDBG": "",
|
||||||
|
@ -41,6 +41,7 @@ set(_OverridableOptions
|
|||||||
"WCHAR"
|
"WCHAR"
|
||||||
"WINDOWS_SEH"
|
"WINDOWS_SEH"
|
||||||
"GETENV"
|
"GETENV"
|
||||||
|
"EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT"
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(OptionName ${_OverridableOptions})
|
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_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_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_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
|
# Catch2's build breaks if done in-tree. You probably should not build
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"CATCH_BUILD_EXAMPLES": "ON",
|
"CATCH_BUILD_EXAMPLES": "ON",
|
||||||
"CATCH_BUILD_EXTRA_TESTS": "ON",
|
"CATCH_BUILD_EXTRA_TESTS": "ON",
|
||||||
"CATCH_BUILD_SURROGATES": "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(
|
http_archive(
|
||||||
name = "bazel_skylib",
|
name = "bazel_skylib",
|
||||||
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
|
sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
|
||||||
urls = [
|
urls = [
|
||||||
"https://mirror.bazel.build/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.1/bazel-skylib-1.4.1.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>
|
[Enabling stringification](#enabling-stringification)<br>
|
||||||
[Disabling exceptions](#disabling-exceptions)<br>
|
[Disabling exceptions](#disabling-exceptions)<br>
|
||||||
[Overriding Catch's debug break (`-b`)](#overriding-catchs-debug-break--b)<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
|
Catch2 is designed to "just work" as much as possible, and most of the
|
||||||
configuration options below are changed automatically during compilation,
|
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
|
examples, specifically
|
||||||
[Generators: Create your own generator](../examples/300-Gen-OwnGenerator.cpp).
|
[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.
|
uses ANSI colour codes for colouring the output.
|
||||||
|
|
||||||
Using multiple reporters (or one reporter and one-or-more [event
|
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
|
when using customization points provided to reporters by Catch2, namely
|
||||||
capturing stdout/stderr from test cases.
|
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)
|
be overridden using the [--allow-running-no-tests](command-line.md#no-tests-override)
|
||||||
flag.
|
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
|
## Passing and failing test cases
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ function(catch_discover_tests_impl)
|
|||||||
)
|
)
|
||||||
endif()
|
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}")
|
string(REPLACE "\n" ";" output "${output}")
|
||||||
|
|
||||||
# Prepare reporter
|
# Prepare reporter
|
||||||
@ -119,15 +123,16 @@ function(catch_discover_tests_impl)
|
|||||||
|
|
||||||
# Parse output
|
# Parse output
|
||||||
foreach(line ${output})
|
foreach(line ${output})
|
||||||
set(test ${line})
|
set(test "${line}")
|
||||||
# Escape characters in test case names that would be parsed by Catch2
|
# Escape characters in test case names that would be parsed by Catch2
|
||||||
set(test_name ${test})
|
# Note that the \ escaping must happen FIRST! Do not change the order.
|
||||||
foreach(char , [ ])
|
set(test_name "${test}")
|
||||||
string(REPLACE ${char} "\\${char}" test_name ${test_name})
|
foreach(char \\ , [ ])
|
||||||
|
string(REPLACE ${char} "\\${char}" test_name "${test_name}")
|
||||||
endforeach(char)
|
endforeach(char)
|
||||||
# ...add output dir
|
# ...add output dir
|
||||||
if(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}")
|
set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ set(IMPL_HEADERS
|
|||||||
${SOURCES_DIR}/internal/catch_compiler_capabilities.hpp
|
${SOURCES_DIR}/internal/catch_compiler_capabilities.hpp
|
||||||
${SOURCES_DIR}/internal/catch_config_android_logwrite.hpp
|
${SOURCES_DIR}/internal/catch_config_android_logwrite.hpp
|
||||||
${SOURCES_DIR}/internal/catch_config_counter.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_uncaught_exceptions.hpp
|
||||||
${SOURCES_DIR}/internal/catch_config_wchar.hpp
|
${SOURCES_DIR}/internal/catch_config_wchar.hpp
|
||||||
${SOURCES_DIR}/internal/catch_console_colour.hpp
|
${SOURCES_DIR}/internal/catch_console_colour.hpp
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||||
#include <catch2/internal/catch_config_android_logwrite.hpp>
|
#include <catch2/internal/catch_config_android_logwrite.hpp>
|
||||||
#include <catch2/internal/catch_config_counter.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_uncaught_exceptions.hpp>
|
||||||
#include <catch2/internal/catch_config_wchar.hpp>
|
#include <catch2/internal/catch_config_wchar.hpp>
|
||||||
#include <catch2/internal/catch_console_colour.hpp>
|
#include <catch2/internal/catch_console_colour.hpp>
|
||||||
|
@ -169,6 +169,15 @@
|
|||||||
#endif
|
#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
|
// Simple toggle defines
|
||||||
// their value is never used and they cannot be overridden
|
// 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
|
#define CATCH_SECTION_HPP_INCLUDED
|
||||||
|
|
||||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||||
|
#include <catch2/internal/catch_config_static_analysis_support.hpp>
|
||||||
#include <catch2/internal/catch_noncopyable.hpp>
|
#include <catch2/internal/catch_noncopyable.hpp>
|
||||||
#include <catch2/catch_section_info.hpp>
|
#include <catch2/catch_section_info.hpp>
|
||||||
#include <catch2/catch_timer.hpp>
|
#include <catch2/catch_timer.hpp>
|
||||||
@ -38,16 +39,62 @@ namespace Catch {
|
|||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
|
||||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
# define INTERNAL_CATCH_SECTION( ... ) \
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||||
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
|
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
||||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
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
|
#endif // CATCH_SECTION_HPP_INCLUDED
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
|
#ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||||
#define 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_source_line_info.hpp>
|
||||||
#include <catch2/internal/catch_noncopyable.hpp>
|
#include <catch2/internal/catch_noncopyable.hpp>
|
||||||
#include <catch2/interfaces/catch_interfaces_test_invoker.hpp>
|
#include <catch2/interfaces/catch_interfaces_test_invoker.hpp>
|
||||||
@ -72,6 +73,9 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
void TestName::test()
|
void TestName::test()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
|
||||||
static void TestName(); \
|
static void TestName(); \
|
||||||
@ -84,19 +88,40 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
#define INTERNAL_CATCH_TESTCASE( ... ) \
|
||||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
|
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||||
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
|
|
||||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
|
||||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
// Dummy registrator for the dumy test case macros
|
||||||
CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
|
namespace Catch {
|
||||||
namespace { \
|
namespace Detail {
|
||||||
const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
|
struct DummyUse {
|
||||||
Catch::makeTestInvoker( &QualifiedMethod ), \
|
DummyUse( void ( * )( int ) );
|
||||||
CATCH_INTERNAL_LINEINFO, \
|
};
|
||||||
"&" #QualifiedMethod##_catch_sr, \
|
} // namespace Detail
|
||||||
Catch::NameAndTags{ __VA_ARGS__ } ); \
|
} // namespace Catch
|
||||||
} /* NOLINT */ \
|
|
||||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
// 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, ... )\
|
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||||
@ -118,6 +143,22 @@ struct AutoReg : Detail::NonCopyable {
|
|||||||
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
|
||||||
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
|
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, ... ) \
|
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -78,6 +78,7 @@ internal_headers = [
|
|||||||
'internal/catch_compiler_capabilities.hpp',
|
'internal/catch_compiler_capabilities.hpp',
|
||||||
'internal/catch_config_android_logwrite.hpp',
|
'internal/catch_config_android_logwrite.hpp',
|
||||||
'internal/catch_config_counter.hpp',
|
'internal/catch_config_counter.hpp',
|
||||||
|
'internal/catch_config_static_analysis_support.hpp',
|
||||||
'internal/catch_config_uncaught_exceptions.hpp',
|
'internal/catch_config_uncaught_exceptions.hpp',
|
||||||
'internal/catch_config_wchar.hpp',
|
'internal/catch_config_wchar.hpp',
|
||||||
'internal/catch_console_colour.hpp',
|
'internal/catch_console_colour.hpp',
|
||||||
|
@ -622,6 +622,18 @@ if (CATCH_ENABLE_CONFIGURE_TESTS)
|
|||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
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
|
foreach (reporterName # "Automake" - the simple .trs format does not support any kind of comments/metadata
|
||||||
"compact"
|
"compact"
|
||||||
"console"
|
"console"
|
||||||
|
@ -130,6 +130,7 @@ Nor would this
|
|||||||
:test-result: FAIL Custom std-exceptions can be custom translated
|
:test-result: FAIL Custom std-exceptions can be custom translated
|
||||||
:test-result: PASS Default scale is invisible to comparison
|
:test-result: PASS Default scale is invisible to comparison
|
||||||
:test-result: PASS Directly creating an EnumInfo
|
: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: PASS Empty stream name opens cout stream
|
||||||
:test-result: FAIL EndsWith string matcher
|
:test-result: FAIL EndsWith string matcher
|
||||||
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
|
: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: FAIL Custom std-exceptions can be custom translated
|
||||||
:test-result: PASS Default scale is invisible to comparison
|
:test-result: PASS Default scale is invisible to comparison
|
||||||
:test-result: PASS Directly creating an EnumInfo
|
: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: PASS Empty stream name opens cout stream
|
||||||
:test-result: FAIL EndsWith string matcher
|
:test-result: FAIL EndsWith string matcher
|
||||||
:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM
|
: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 **}
|
ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **}
|
||||||
==
|
==
|
||||||
"{** 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
|
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( "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)
|
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
|
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:
|
||||||
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
|
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 **}
|
ToString.tests.cpp:<line number>: passed: enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **}
|
||||||
==
|
==
|
||||||
"{** 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
|
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( "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)
|
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
|
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:
|
||||||
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
|
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:
|
due to unexpected exception with message:
|
||||||
custom std exception
|
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
|
EndsWith string matcher
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -1533,6 +1543,6 @@ due to unexpected exception with message:
|
|||||||
Why would you throw a std::string?
|
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
|
assertions: 2208 | 2048 passed | 128 failed | 32 failed as expected
|
||||||
|
|
||||||
|
@ -3956,6 +3956,16 @@ with expansion:
|
|||||||
==
|
==
|
||||||
"{** unexpected enum value **}"
|
"{** 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
|
Empty stream name opens cout stream
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -18222,6 +18232,6 @@ Misc.tests.cpp:<line number>
|
|||||||
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
|
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||||
|
|
||||||
|
@ -3954,6 +3954,16 @@ with expansion:
|
|||||||
==
|
==
|
||||||
"{** unexpected enum value **}"
|
"{** 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
|
Empty stream name opens cout stream
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -18211,6 +18221,6 @@ Misc.tests.cpp:<line number>
|
|||||||
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
|
assertions: 2225 | 2048 passed | 145 failed | 32 failed as expected
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<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>
|
<properties>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||||
@ -462,6 +462,13 @@ at Exception.tests.cpp:<line number>
|
|||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
|
<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="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="Empty stream name opens cout stream" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="EndsWith string matcher" 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">
|
<failure message="testStringForMatching(), EndsWith( "Substring" )" type="CHECK_THAT">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuites>
|
<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>
|
<properties>
|
||||||
<property name="random-seed" value="1"/>
|
<property name="random-seed" value="1"/>
|
||||||
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
<property name="filters" value=""*" ~[!nonportable] ~[!benchmark] ~[approvals]"/>
|
||||||
@ -461,6 +461,13 @@ at Exception.tests.cpp:<line number>
|
|||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Default scale is invisible to comparison" time="{duration}" status="run"/>
|
<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="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="Empty stream name opens cout stream" time="{duration}" status="run"/>
|
||||||
<testcase classname="<exe-name>.global" name="EndsWith string matcher" 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">
|
<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}"/>
|
<testCase name="xmlentitycheck/encoded chars: these should all be encoded: &&&"""<<<&"<<&"" duration="{duration}"/>
|
||||||
</file>
|
</file>
|
||||||
<file path="tests/<exe-name>/UsageTests/Skip.tests.cpp">
|
<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}">
|
<testCase name="a succeeding test can still be skipped" duration="{duration}">
|
||||||
<skipped message="SKIP()">
|
<skipped message="SKIP()">
|
||||||
SKIPPED
|
SKIPPED
|
||||||
|
@ -1869,6 +1869,13 @@ at Misc.tests.cpp:<line number>
|
|||||||
<testCase name="xmlentitycheck/encoded chars: these should all be encoded: &&&"""<<<&"<<&"" duration="{duration}"/>
|
<testCase name="xmlentitycheck/encoded chars: these should all be encoded: &&&"""<<<&"<<&"" duration="{duration}"/>
|
||||||
</file>
|
</file>
|
||||||
<file path="tests/<exe-name>/UsageTests/Skip.tests.cpp">
|
<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}">
|
<testCase name="a succeeding test can still be skipped" duration="{duration}">
|
||||||
<skipped message="SKIP()">
|
<skipped message="SKIP()">
|
||||||
SKIPPED
|
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"
|
ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
|
||||||
# Directly creating an EnumInfo
|
# Directly creating an EnumInfo
|
||||||
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
|
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
|
# Empty stream name opens cout stream
|
||||||
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
||||||
# EndsWith string matcher
|
# EndsWith string matcher
|
||||||
@ -4475,5 +4477,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
|||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# xmlentitycheck
|
# xmlentitycheck
|
||||||
ok {test-number} -
|
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"
|
ok {test-number} - enumInfo->lookup(1) == "Value2" for: Value2 == "Value2"
|
||||||
# Directly creating an EnumInfo
|
# Directly creating an EnumInfo
|
||||||
ok {test-number} - enumInfo->lookup(3) == "{** unexpected enum value **}" for: {** unexpected enum value **} == "{** unexpected enum value **}"
|
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
|
# Empty stream name opens cout stream
|
||||||
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
ok {test-number} - Catch::makeStream( "" )->isConsole() for: true
|
||||||
# EndsWith string matcher
|
# EndsWith string matcher
|
||||||
@ -4464,5 +4466,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
|
|||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
# xmlentitycheck
|
# xmlentitycheck
|
||||||
ok {test-number} -
|
ok {test-number} -
|
||||||
1..2236
|
1..2237
|
||||||
|
|
||||||
|
@ -299,6 +299,9 @@
|
|||||||
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
||||||
##teamcity[testStarted name='Directly creating an EnumInfo']
|
##teamcity[testStarted name='Directly creating an EnumInfo']
|
||||||
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
|
##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[testStarted name='Empty stream name opens cout stream']
|
||||||
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
||||||
##teamcity[testStarted name='EndsWith string matcher']
|
##teamcity[testStarted name='EndsWith string matcher']
|
||||||
|
@ -299,6 +299,9 @@
|
|||||||
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
##teamcity[testFinished name='Default scale is invisible to comparison' duration="{duration}"]
|
||||||
##teamcity[testStarted name='Directly creating an EnumInfo']
|
##teamcity[testStarted name='Directly creating an EnumInfo']
|
||||||
##teamcity[testFinished name='Directly creating an EnumInfo' duration="{duration}"]
|
##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[testStarted name='Empty stream name opens cout stream']
|
||||||
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
##teamcity[testFinished name='Empty stream name opens cout stream' duration="{duration}"]
|
||||||
##teamcity[testStarted name='EndsWith string matcher']
|
##teamcity[testStarted name='EndsWith string matcher']
|
||||||
|
@ -4364,6 +4364,12 @@ C
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</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" >
|
<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" >
|
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@ -21192,6 +21198,6 @@ b1!
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
|
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="12"/>
|
||||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
|
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="6"/>
|
||||||
</Catch2TestRun>
|
</Catch2TestRun>
|
||||||
|
@ -4364,6 +4364,12 @@ C
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</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" >
|
<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" >
|
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/Stream.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@ -21191,6 +21197,6 @@ b1!
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true" skips="0"/>
|
<OverallResult success="true" skips="0"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="11"/>
|
<OverallResults successes="2048" failures="145" expectedFailures="32" skips="12"/>
|
||||||
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="5"/>
|
<OverallResultsCases successes="308" failures="84" expectedFailures="11" skips="6"/>
|
||||||
</Catch2TestRun>
|
</Catch2TestRun>
|
||||||
|
@ -95,8 +95,8 @@ namespace {
|
|||||||
MoveChecker() = default;
|
MoveChecker() = default;
|
||||||
MoveChecker( MoveChecker const& rhs ) = default;
|
MoveChecker( MoveChecker const& rhs ) = default;
|
||||||
MoveChecker& operator=( MoveChecker const& rhs ) = default;
|
MoveChecker& operator=( MoveChecker const& rhs ) = default;
|
||||||
MoveChecker( MoveChecker&& rhs ) { rhs.has_moved = true; }
|
MoveChecker( MoveChecker&& rhs ) noexcept { rhs.has_moved = true; }
|
||||||
MoveChecker& operator=( MoveChecker&& rhs ) {
|
MoveChecker& operator=( MoveChecker&& rhs ) noexcept {
|
||||||
rhs.has_moved = true;
|
rhs.has_moved = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ namespace {
|
|||||||
std::vector<std::string>& recorder,
|
std::vector<std::string>& recorder,
|
||||||
Catch::IConfig const* config ):
|
Catch::IConfig const* config ):
|
||||||
EventListenerBase( config ),
|
EventListenerBase( config ),
|
||||||
m_witness( witness ),
|
m_witness( CATCH_MOVE(witness) ),
|
||||||
m_recorder( recorder )
|
m_recorder( recorder )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ namespace {
|
|||||||
std::vector<std::string>& recorder,
|
std::vector<std::string>& recorder,
|
||||||
Catch::ReporterConfig&& config ):
|
Catch::ReporterConfig&& config ):
|
||||||
StreamingReporterBase( CATCH_MOVE(config) ),
|
StreamingReporterBase( CATCH_MOVE(config) ),
|
||||||
m_witness( witness ),
|
m_witness( CATCH_MOVE(witness) ),
|
||||||
m_recorder( recorder )
|
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]") {
|
TEST_CASE("#1913 - GENERATE inside a for loop should not keep recreating the generator", "[regression][generators]") {
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
for (int i = 0; i < 3; ++i) {
|
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
|
// this should fail the test case, but not abort the application
|
||||||
auto sample = GENERATE( make_test_generator() );
|
auto sample = GENERATE( make_test_generator() );
|
||||||
// this assertion shouldn't trigger
|
// 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\"";
|
return "equals: (int) 1 or (string) \"1\"";
|
||||||
}
|
}
|
||||||
bool match( int i ) const { return i == 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 {
|
struct MatcherB : Catch::Matchers::MatcherGenericBase {
|
||||||
|
@ -71,3 +71,30 @@ TEST_CASE( "failing for some generator values causes entire test case to fail",
|
|||||||
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