mirror of
https://github.com/catchorg/Catch2.git
synced 2025-10-05 19:41:09 +02:00
Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7ee2173aca | ||
|
20d3f1939d | ||
|
459ac8562b | ||
|
8ac8190e49 | ||
|
b20b365fd2 | ||
|
4d8affc989 | ||
|
cde3509664 | ||
|
7677c1658e | ||
|
92d3b23913 | ||
|
dca87563bb | ||
|
da303cc668 | ||
|
c3fd4eb17e | ||
|
fb51116d5b | ||
|
ed6ac8a629 | ||
|
e7913f1363 | ||
|
4f3871d53f | ||
|
f476bcb633 | ||
|
024cfb3542 | ||
|
28c2f0b0c2 | ||
|
2e1b02a0e2 | ||
|
82e9b9b5f2 | ||
|
031a163a2c | ||
|
562f31029a | ||
|
62d4aecb8c | ||
|
b817497528 | ||
|
4f1b24df77 | ||
|
3157d6bbf1 | ||
|
4570fca24b | ||
|
0787132fc8 | ||
|
dc51386b9f | ||
|
bbba3d8a06 | ||
|
d937427f1f | ||
|
2a5de4e447 | ||
|
1078e7e95b | ||
|
79205da6a6 | ||
|
658acee86e |
81
.clang-tidy
Normal file
81
.clang-tidy
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
# Note: Alas, `Checks` is a string, not an array.
|
||||
# Comments in the block string are not parsed and are passed in the value.
|
||||
# They must thus be delimited by ',' from either side - then they are
|
||||
# harmless. It's terrible, but it works.
|
||||
Checks: >-
|
||||
clang-diagnostic-*,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-optin.core.EnumCastOutOfRange,
|
||||
|
||||
bugprone-*,
|
||||
-bugprone-unchecked-optional-access,
|
||||
,# This is ridiculous, as it triggers on constants,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
,# Is not really useful, has false positives, triggers for no-noexcept move constructors ...,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-narrowing-conversions,
|
||||
-bugprone-chained-comparison,# RIP decomposers,
|
||||
|
||||
modernize-*,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-use-auto,
|
||||
-modernize-use-emplace,
|
||||
-modernize-use-nullptr,# it went crazy with three-way comparison operators,
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-return-braced-init-list,
|
||||
-modernize-concat-nested-namespaces,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-use-default-member-init,
|
||||
-modernize-type-traits,# we need to support C++14,
|
||||
-modernize-deprecated-headers,
|
||||
,# There's a lot of these and most of them are probably not useful,
|
||||
-modernize-pass-by-value,
|
||||
|
||||
performance-*,
|
||||
-performance-enum-size,
|
||||
|
||||
portability-*,
|
||||
|
||||
readability-*,
|
||||
-readability-braces-around-statements,
|
||||
-readability-container-size-empty,
|
||||
-readability-convert-member-functions-to-static,
|
||||
-readability-else-after-return,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-function-size,
|
||||
-readability-identifier-length,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-isolate-declaration,
|
||||
-readability-magic-numbers,
|
||||
-readability-named-parameter,
|
||||
-readability-qualified-auto,
|
||||
-readability-redundant-access-specifiers,
|
||||
-readability-simplify-boolean-expr,
|
||||
-readability-static-definition-in-anonymous-namespace,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-readability-use-anyofallof,
|
||||
-readability-avoid-return-with-void-value,
|
||||
|
||||
,# time hogs,
|
||||
-bugprone-throw-keyword-missing,
|
||||
-modernize-replace-auto-ptr,
|
||||
-readability-identifier-naming,
|
||||
|
||||
,# We cannot use this until clang-tidy supports custom unique_ptr,
|
||||
-bugprone-use-after-move,
|
||||
,# Doesn't recognize unevaluated context in CATCH_MOVE and CATCH_FORWARD,
|
||||
-bugprone-macro-repeated-side-effects,
|
||||
WarningsAsErrors: >-
|
||||
clang-analyzer-core.*,
|
||||
clang-analyzer-cplusplus.*,
|
||||
clang-analyzer-security.*,
|
||||
clang-analyzer-unix.*,
|
||||
performance-move-const-arg,
|
||||
performance-unnecessary-value-param,
|
||||
readability-duplicate-include,
|
||||
HeaderFilterRegex: '.*\.(c|cxx|cpp)$'
|
||||
FormatStyle: none
|
||||
CheckOptions: {}
|
||||
...
|
@@ -1,12 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.2.0)
|
||||
project(test_package CXX)
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(PackageTest CXX)
|
||||
|
||||
include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
|
||||
conan_basic_setup()
|
||||
find_package(Catch2 CONFIG REQUIRED)
|
||||
|
||||
find_package(Catch2 REQUIRED CONFIG)
|
||||
|
||||
add_executable(${PROJECT_NAME} test_package.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Catch2::Catch2WithMain)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14)
|
||||
add_executable(test_package test_package.cpp)
|
||||
target_link_libraries(test_package Catch2::Catch2WithMain)
|
@@ -1,12 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from conans import ConanFile, CMake
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import CMake, cmake_layout
|
||||
from conan.tools.build import can_run
|
||||
import os
|
||||
|
||||
|
||||
class TestPackageConan(ConanFile):
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "cmake_find_package_multi", "cmake"
|
||||
generators = "CMakeToolchain", "CMakeDeps"
|
||||
|
||||
def requirements(self):
|
||||
self.requires(self.tested_reference_str)
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
@@ -14,7 +22,12 @@ class TestPackageConan(ConanFile):
|
||||
cmake.build()
|
||||
|
||||
def test(self):
|
||||
assert os.path.isfile(os.path.join(
|
||||
self.deps_cpp_info["catch2"].rootpath, "licenses", "LICENSE.txt"))
|
||||
bin_path = os.path.join("bin", "test_package")
|
||||
self.run("%s -s" % bin_path, run_environment=True)
|
||||
if can_run(self):
|
||||
cmd = os.path.join(self.cpp.build.bindir, "test_package")
|
||||
self.run(cmd, env="conanrun")
|
||||
|
||||
# If we are on conan 2 we can check the license info is populated
|
||||
if hasattr(self, 'dependencies'):
|
||||
catch2 = self.dependencies["catch2"]
|
||||
assert os.path.exists(f'{catch2.package_folder}/licenses/LICENSE.txt')
|
||||
assert catch2.license == 'BSL-1.0'
|
||||
|
1
.github/workflows/linux-meson-builds.yml
vendored
1
.github/workflows/linux-meson-builds.yml
vendored
@@ -40,6 +40,5 @@ jobs:
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ${{runner.workspace}}/meson-build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: |
|
||||
meson test --verbose
|
||||
|
52
.github/workflows/linux-other-builds.yml
vendored
52
.github/workflows/linux-other-builds.yml
vendored
@@ -102,5 +102,53 @@ jobs:
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: ctest -C ${{matrix.build_type}} -j 2 ${{matrix.other_ctest_args}}
|
||||
run: ctest -C ${{matrix.build_type}} -j `nproc` ${{matrix.other_ctest_args}}
|
||||
clang-tidy:
|
||||
name: clang-tidy ${{matrix.version}}, ${{matrix.build_description}}, C++${{matrix.std}} ${{matrix.build_type}}
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- version: "15"
|
||||
build_description: all
|
||||
build_type: Debug
|
||||
std: 17
|
||||
other_pkgs: ''
|
||||
cmake_configurations: -DCATCH_BUILD_EXAMPLES=ON -DCATCH_ENABLE_CMAKE_HELPER_TESTS=ON
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ninja-build clang-${{matrix.version}} clang-tidy-${{matrix.version}} ${{matrix.other_pkgs}}
|
||||
|
||||
- name: Configure build
|
||||
working-directory: ${{runner.workspace}}
|
||||
env:
|
||||
CXX: clang++-${{matrix.version}}
|
||||
CXXFLAGS: ${{matrix.cxxflags}}
|
||||
# Note: $GITHUB_WORKSPACE is distinct from ${{runner.workspace}}.
|
||||
# This is important
|
||||
run: |
|
||||
clangtidy="clang-tidy-${{matrix.version}};-use-color"
|
||||
# Use a dummy compiler/linker/ar/ranlib to effectively disable the
|
||||
# compilation and only run clang-tidy.
|
||||
cmake -Bbuild -H$GITHUB_WORKSPACE \
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
|
||||
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
-DCMAKE_CXX_EXTENSIONS=OFF \
|
||||
-DCATCH_DEVELOPMENT_BUILD=ON \
|
||||
-DCMAKE_CXX_CLANG_TIDY="$clangtidy" \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/true \
|
||||
-DCMAKE_AR=/usr/bin/true \
|
||||
-DCMAKE_CXX_COMPILER_AR=/usr/bin/true \
|
||||
-DCMAKE_RANLIB=/usr/bin/true \
|
||||
-DCMAKE_CXX_LINK_EXECUTABLE=/usr/bin/true \
|
||||
${{matrix.cmake_configurations}} \
|
||||
-G Ninja
|
||||
|
||||
- name: Run clang-tidy
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
run: ninja
|
||||
|
9
.github/workflows/linux-simple-builds.yml
vendored
9
.github/workflows/linux-simple-builds.yml
vendored
@@ -9,8 +9,6 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
- g++-5
|
||||
- g++-6
|
||||
- g++-7
|
||||
- g++-8
|
||||
- g++-9
|
||||
@@ -23,10 +21,6 @@ jobs:
|
||||
build_type: [Debug, Release]
|
||||
std: [14]
|
||||
include:
|
||||
- cxx: g++-5
|
||||
other_pkgs: g++-5
|
||||
- cxx: g++-6
|
||||
other_pkgs: g++-6
|
||||
- cxx: g++-7
|
||||
other_pkgs: g++-7
|
||||
- cxx: g++-8
|
||||
@@ -120,5 +114,4 @@ jobs:
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: 1
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Hardcode 2 cores we know are there
|
||||
run: ctest -C ${{matrix.build_type}} -j 2
|
||||
run: ctest -C ${{matrix.build_type}} -j `nproc`
|
||||
|
6
.github/workflows/mac-builds.yml
vendored
6
.github/workflows/mac-builds.yml
vendored
@@ -4,11 +4,7 @@ on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# macos-12 updated to a toolchain that crashes when linking the
|
||||
# test binary. This seems to be a known bug in that version,
|
||||
# and will eventually get fixed in an update. After that, we can go
|
||||
# back to newer macos images.
|
||||
runs-on: macos-11
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
matrix:
|
||||
cxx:
|
||||
|
31
.github/workflows/package-manager-builds.yaml
vendored
Normal file
31
.github/workflows/package-manager-builds.yaml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Package Manager Builds
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
conan_builds:
|
||||
name: Conan ${{matrix.conan_version}}
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
conan_version:
|
||||
- '1.62'
|
||||
- '2.0'
|
||||
|
||||
include:
|
||||
# Conan 1 has default profiles installed
|
||||
- conan_version: '1.62'
|
||||
profile_generate: 'false'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install conan
|
||||
run: pip install conan==${{matrix.conan_version}}
|
||||
|
||||
- name: Setup conan profiles
|
||||
if: matrix.profile_generate != 'false'
|
||||
run: conan profile detect
|
||||
|
||||
- name: Run conan package create
|
||||
run: conan create . -tf .conan/test_package
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,6 +25,7 @@ Build
|
||||
cmake-build-*
|
||||
benchmark-dir
|
||||
.conan/test_package/build
|
||||
.conan/test_package/CMakeUserPresets.json
|
||||
bazel-*
|
||||
build-fuzzers
|
||||
debug-build
|
||||
|
@@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
endif()
|
||||
|
||||
project(Catch2
|
||||
VERSION 3.5.2 # CML version placeholder, don't delete
|
||||
VERSION 3.5.3 # CML version placeholder, don't delete
|
||||
LANGUAGES CXX
|
||||
# HOMEPAGE_URL is not supported until CMake version 3.12, which
|
||||
# we do not target yet.
|
||||
|
15
appveyor.yml
15
appveyor.yml
@@ -5,10 +5,10 @@ version: "{build}-{branch}"
|
||||
clone_depth: 20
|
||||
|
||||
# We want to build everything, except for branches that are explicitly
|
||||
# for messing around with travis.
|
||||
# for messing around with Github Actions.
|
||||
branches:
|
||||
except:
|
||||
- /dev-travis.+/
|
||||
- /devel-gha.+/
|
||||
|
||||
|
||||
# We need a more up to date pip because Python 2.7 is EOL soon
|
||||
@@ -70,3 +70,14 @@ environment:
|
||||
additional_flags: "/permissive- /std:c++latest"
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 x64 Debug
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
||||
- FLAVOR: VS 2017 x64 Release Coverage
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
coverage: 1
|
||||
platform: x64
|
||||
configuration: Debug
|
||||
|
73
conanfile.py
Normal file → Executable file
73
conanfile.py
Normal file → Executable file
@@ -1,5 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
from conans import ConanFile, CMake, tools
|
||||
from conan import ConanFile, tools, __version__ as conan_version
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
|
||||
from conan.tools import files, scm
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
||||
required_conan_version = ">=1.53.0"
|
||||
|
||||
class CatchConan(ConanFile):
|
||||
name = "catch2"
|
||||
@@ -8,53 +15,73 @@ class CatchConan(ConanFile):
|
||||
url = "https://github.com/catchorg/Catch2"
|
||||
homepage = url
|
||||
license = "BSL-1.0"
|
||||
version = "latest"
|
||||
|
||||
exports = "LICENSE.txt"
|
||||
exports_sources = ("src/*", "CMakeLists.txt", "CMake/*", "extras/*")
|
||||
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
|
||||
generators = "cmake"
|
||||
def set_version(self):
|
||||
pattern = re.compile(r"\w*VERSION (\d+\.\d+\.\d+) # CML version placeholder, don't delete")
|
||||
with open("CMakeLists.txt") as file:
|
||||
for line in file:
|
||||
result = pattern.search(line)
|
||||
if result:
|
||||
self.version = result.group(1)
|
||||
|
||||
self.output.info(f'Using version: {self.version}')
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.generate()
|
||||
|
||||
deps = CMakeDeps(self)
|
||||
deps.generate()
|
||||
|
||||
def _configure_cmake(self):
|
||||
cmake = CMake(self)
|
||||
cmake.definitions["BUILD_TESTING"] = "OFF"
|
||||
cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
|
||||
cmake.definitions["CATCH_INSTALL_EXTRAS"] = "ON"
|
||||
cmake.configure(build_folder="build")
|
||||
|
||||
# These are option variables. The toolchain in conan 2 doesn't appear to
|
||||
# set these correctly so you have to do it in the configure variables.
|
||||
cmake.configure(variables= {
|
||||
"BUILD_TESTING": "OFF",
|
||||
"CATCH_INSTALL_DOCS": "OFF",
|
||||
"CATCH_INSTALL_EXTRAS": "ON",
|
||||
}
|
||||
)
|
||||
return cmake
|
||||
|
||||
def build(self):
|
||||
# We need this workaround until the toolchains feature
|
||||
# to inject stuff like MD/MT
|
||||
line_to_replace = 'list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")'
|
||||
tools.replace_in_file("CMakeLists.txt", line_to_replace,
|
||||
'''{}
|
||||
include("{}/conanbuildinfo.cmake")
|
||||
conan_basic_setup()'''.format(line_to_replace, self.install_folder.replace("\\", "/")))
|
||||
|
||||
cmake = self._configure_cmake()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
self.copy(pattern="LICENSE.txt", dst="licenses")
|
||||
cmake = self._configure_cmake()
|
||||
cmake.install()
|
||||
|
||||
os.mkdir(f'{self.package_folder}/licenses/')
|
||||
shutil.copy2(f'{self.recipe_folder}/LICENSE.txt', f'{self.package_folder}/licenses/')
|
||||
|
||||
def package_info(self):
|
||||
lib_suffix = "d" if self.settings.build_type == "Debug" else ""
|
||||
|
||||
self.cpp_info.names["cmake_find_package"] = "Catch2"
|
||||
self.cpp_info.names["cmake_find_package_multi"] = "Catch2"
|
||||
self.cpp_info.set_property("cmake_file_name", "Catch2")
|
||||
self.cpp_info.set_property("cmake_target_name", "Catch2::Catch2WithMain")
|
||||
self.cpp_info.set_property("pkg_config_name", "catch2-with-main")
|
||||
|
||||
# Catch2
|
||||
self.cpp_info.components["catch2base"].names["cmake_find_package"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].names["cmake_find_package_multi"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].names["pkg_config"] = "Catch2"
|
||||
self.cpp_info.components["catch2base"].set_property("cmake_file_name", "Catch2::Catch2")
|
||||
self.cpp_info.components["catch2base"].set_property("pkg_config_name", "catch2")
|
||||
self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix]
|
||||
self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2")
|
||||
|
||||
# Catch2WithMain
|
||||
self.cpp_info.components["catch2main"].names["cmake_find_package"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].names["cmake_find_package_multi"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].names["pkg_config"] = "Catch2WithMain"
|
||||
self.cpp_info.components["catch2main"].set_property("cmake_file_name", "Catch2::Catch2WithMain")
|
||||
self.cpp_info.components["catch2main"].set_property("cmake_target_name", "Catch2::Catch2WithMain")
|
||||
self.cpp_info.components["catch2main"].set_property("pkg_config_name", "catch2-with-main")
|
||||
self.cpp_info.components["catch2main"].libs = ["Catch2Main" + lib_suffix]
|
||||
self.cpp_info.components["catch2main"].requires = ["catch2base"]
|
@@ -384,7 +384,7 @@ install it to the default location, like so:
|
||||
```
|
||||
$ git clone https://github.com/catchorg/Catch2.git
|
||||
$ cd Catch2
|
||||
$ cmake -Bbuild -H. -DBUILD_TESTING=OFF
|
||||
$ cmake -B build -S . -DBUILD_TESTING=OFF
|
||||
$ sudo cmake --build build/ --target install
|
||||
```
|
||||
|
||||
@@ -408,6 +408,24 @@ cd vcpkg
|
||||
The catch2 port in vcpkg is kept up to date by microsoft team members and community contributors.
|
||||
If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Installing Catch2 from Bazel
|
||||
|
||||
Catch2 is now a supported module in the Bazel Central Registry. You only need to add one line to your MODULE.bazel file;
|
||||
please see https://registry.bazel.build/modules/catch2 for the latest supported version.
|
||||
|
||||
You can then add `catch2_main` to each of your C++ test build rules as follows:
|
||||
|
||||
```
|
||||
cc_test(
|
||||
name = "example_test",
|
||||
srcs = ["example_test.cpp"],
|
||||
deps = [
|
||||
":example",
|
||||
"@catch2//:catch2_main",
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Home](Readme.md#top)
|
||||
|
@@ -365,14 +365,14 @@ There are currently two warnings implemented:
|
||||
## Reporting timings
|
||||
<pre>-d, --durations <yes/no></pre>
|
||||
|
||||
When set to ```yes``` Catch will report the duration of each test case, in milliseconds. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not.
|
||||
When set to ```yes``` Catch will report the duration of each test case, in seconds with millisecond precision. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not.
|
||||
|
||||
<pre>-D, --min-duration <value></pre>
|
||||
|
||||
> `--min-duration` was [introduced](https://github.com/catchorg/Catch2/pull/1910) in Catch2 2.13.0
|
||||
|
||||
When set, Catch will report the duration of each test case that took more
|
||||
than <value> seconds, in milliseconds. This option is overridden by both
|
||||
than <value> seconds, in seconds with millisecond precision. This option is overridden by both
|
||||
`-d yes` and `-d no`, so that either all durations are reported, or none
|
||||
are.
|
||||
|
||||
|
@@ -206,12 +206,26 @@ or OO ranges.
|
||||
Unlike `std::uniform_int_distribution`, Catch2's generators also support
|
||||
various single-byte integral types, such as `char` or `bool`.
|
||||
|
||||
Given the same seed, the output from the integral generators is
|
||||
reproducible across different platforms. For floating point generators,
|
||||
we only promise reproducibility on platforms that obey the IEEE 754
|
||||
standard, and where `float` is 4 bytes and `double` is 8 bytes. We provide
|
||||
no guarantees for `long double`, as the internals of `long double` can
|
||||
vary wildly across different platforms.
|
||||
|
||||
#### Reproducibility
|
||||
|
||||
Given the same seed, the output from the integral generators is fully
|
||||
reproducible across different platforms.
|
||||
|
||||
For floating point generators, the situation is much more complex.
|
||||
Generally Catch2 only promises reproducibility (or even just correctness!)
|
||||
on platforms that obey the IEEE-754 standard. Furthermore, reproducibility
|
||||
only applies between binaries that perform floating point math in the
|
||||
same way, e.g. if you compile a binary targetting the x87 FPU and another
|
||||
one targetting SSE2 for floating point math, their results will vary.
|
||||
Similarly, binaries compiled with compiler flags that relax the IEEE-754
|
||||
adherence, e.g. `-ffast-math`, might provide different results than those
|
||||
compiled for strict IEEE-754 adherence.
|
||||
|
||||
Finally, we provide zero guarantees on the reproducibility of generating
|
||||
`long double`s, as the internals of `long double` varies across different
|
||||
platforms.
|
||||
|
||||
|
||||
|
||||
## Generator interface
|
||||
|
@@ -173,3 +173,19 @@ TEST_CASE("b") {
|
||||
|
||||
If you are seeing a problem like this, i.e. weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library.
|
||||
|
||||
|
||||
### Visual Studio 2022 -- can't compile assertion with the spaceship operator
|
||||
|
||||
[The C++ standard requires that `std::foo_ordering` is only comparable with
|
||||
a literal 0](https://eel.is/c++draft/cmp#categories.pre-3). There are
|
||||
multiple strategies a stdlib implementation can take to achieve this, and
|
||||
MSVC's STL has changed the strategy they use between two releases of VS 2022.
|
||||
|
||||
With the new strategy, `REQUIRE((a <=> b) == 0)` no longer compiles under
|
||||
MSVC. Note that Catch2 can compile code using MSVC STL's new strategy,
|
||||
but only when compiled with a C++20 conforming compiler. MSVC is currently
|
||||
not conformant enough, but `clang-cl` will compile the assertion above
|
||||
using MSVC STL without problem.
|
||||
|
||||
This change got in with MSVC v19.37](https://godbolt.org/z/KG9obzdvE).
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
# Release notes
|
||||
**Contents**<br>
|
||||
[3.5.3](#353)<br>
|
||||
[3.5.2](#352)<br>
|
||||
[3.5.1](#351)<br>
|
||||
[3.5.0](#350)<br>
|
||||
@@ -60,7 +61,32 @@
|
||||
[Even Older versions](#even-older-versions)<br>
|
||||
|
||||
|
||||
## 3.5.1
|
||||
## 3.5.3
|
||||
|
||||
### Fixes
|
||||
* Fixed OOB access when computing filename tag (from the `-#` flag) for file without extension (#2798)
|
||||
* Fixed the linking against `log` on Android to be `PRIVATE` (#2815)
|
||||
* Fixed `Wuseless-cast` in benchmarking internals (#2823)
|
||||
|
||||
### Improvements
|
||||
* Restored compatibility with VS2017 (#2792, #2822)
|
||||
* The baseline for Catch2 is still C++14 with some reasonable workarounds for specific compilers, so if VS2017 starts acting up again, the support will be dropped again.
|
||||
* Suppressed clang-tidy's `bugprone-chained-comparison` in assertions (#2801)
|
||||
* Improved the static analysis mode to evaluate arguments to `TEST_CASE` and `SECTION` (#2817)
|
||||
* Clang-tidy should no longer warn about runtime arguments to these macros being unused in static analysis mode.
|
||||
* Clang-tidy can warn on issues involved arguments to these macros.
|
||||
* Added support for literal-zero detectors based on `consteval` constructors
|
||||
* This is required for compiling `REQUIRE((a <=> b) == 0)` against MSVC's stdlib.
|
||||
* Sadly, MSVC still cannot compile this assertion as it does not implement C++20 correctly.
|
||||
* You can use `clang-cl` with MSVC's stdlib instead.
|
||||
* If for some godforsaken reasons you want to understand this better, read the two relevant commits: [`dc51386b9fd61f99ea9c660d01867e6ad489b403`](https://github.com/catchorg/Catch2/commit/dc51386b9fd61f99ea9c660d01867e6ad489b403), and [`0787132fc82a75e3fb255aa9484ca1dc1eff2a30`](https://github.com/catchorg/Catch2/commit/0787132fc82a75e3fb255aa9484ca1dc1eff2a30).
|
||||
|
||||
### Miscellaneous
|
||||
* Disabled tests for FP random generator reproducibility on non-SSE2 x86 targets (#2796)
|
||||
* Modified the in-tree Conan recipe to support Conan 2 (#2805)
|
||||
|
||||
|
||||
## 3.5.2
|
||||
|
||||
### Fixes
|
||||
* Fixed `-Wsubobject-linkage` in the Console reporter (#2794)
|
||||
|
@@ -5,7 +5,7 @@ Reporters are a customization point for most of Catch2's output, e.g.
|
||||
formatting and writing out [assertions (whether passing or failing),
|
||||
sections, test cases, benchmarks, and so on](reporter-events.md#top).
|
||||
|
||||
Catch2 comes with a bunch of reporters by default (currently 8), and
|
||||
Catch2 comes with a bunch of reporters by default (currently 9), and
|
||||
you can also write your own reporter. Because multiple reporters can
|
||||
be active at the same time, your own reporters do not even have to handle
|
||||
all reporter event, just the ones you are interested in, e.g. benchmarks.
|
||||
|
@@ -16,7 +16,7 @@ Ideally you should be using Catch2 through its [CMake integration](cmake-integra
|
||||
Catch2 also provides pkg-config files and two file (header + cpp)
|
||||
distribution, but this documentation will assume you are using CMake. If
|
||||
you are using the two file distribution instead, remember to replace
|
||||
the included header with `catch_amalgamated.hpp`.
|
||||
the included header with `catch_amalgamated.hpp` ([step by step instructions](migrate-v2-to-v3.md#how-to-migrate-projects-from-v2-to-v3)).
|
||||
|
||||
|
||||
## Writing tests
|
||||
|
@@ -385,8 +385,7 @@ struct MyListener : Catch::EventListenerBase {
|
||||
CATCH_REGISTER_LISTENER( MyListener )
|
||||
|
||||
// Get rid of Wweak-tables
|
||||
MyListener::~MyListener() {}
|
||||
|
||||
MyListener::~MyListener() = default;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 3. Test cases:
|
||||
|
@@ -22,7 +22,7 @@ class out_buff : public std::stringbuf {
|
||||
std::FILE* m_stream;
|
||||
public:
|
||||
out_buff(std::FILE* stream):m_stream(stream) {}
|
||||
~out_buff();
|
||||
~out_buff() override;
|
||||
int sync() override {
|
||||
int ret = 0;
|
||||
for (unsigned char c : str()) {
|
||||
|
@@ -35,7 +35,7 @@ int main(int argc, char** argv) {
|
||||
return returnCode;
|
||||
|
||||
// if set on the command line then 'height' is now set at this point
|
||||
std::cout << "height: " << height << std::endl;
|
||||
std::cout << "height: " << height << '\n';
|
||||
|
||||
return session.run();
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@
|
||||
namespace {
|
||||
|
||||
// This class shows how to implement a simple generator for Catch tests
|
||||
class RandomIntGenerator : public Catch::Generators::IGenerator<int> {
|
||||
class RandomIntGenerator final : public Catch::Generators::IGenerator<int> {
|
||||
std::minstd_rand m_rand;
|
||||
std::uniform_int_distribution<> m_dist;
|
||||
int current_number;
|
||||
|
@@ -24,12 +24,12 @@ namespace {
|
||||
// Returns a line from a stream. You could have it e.g. read lines from
|
||||
// a file, but to avoid problems with paths in examples, we will use
|
||||
// a fixed stringstream.
|
||||
class LineGenerator : public Catch::Generators::IGenerator<std::string> {
|
||||
class LineGenerator final : public Catch::Generators::IGenerator<std::string> {
|
||||
std::string m_line;
|
||||
std::stringstream m_stream;
|
||||
public:
|
||||
LineGenerator() {
|
||||
m_stream.str("1\n2\n3\n4\n");
|
||||
explicit LineGenerator( std::string const& lines ) {
|
||||
m_stream.str( lines );
|
||||
if (!next()) {
|
||||
Catch::Generators::Detail::throw_generator_exception("Couldn't read a single line");
|
||||
}
|
||||
@@ -49,18 +49,19 @@ std::string const& LineGenerator::get() const {
|
||||
// This helper function provides a nicer UX when instantiating the generator
|
||||
// Notice that it returns an instance of GeneratorWrapper<std::string>, which
|
||||
// is a value-wrapper around std::unique_ptr<IGenerator<std::string>>.
|
||||
Catch::Generators::GeneratorWrapper<std::string> lines(std::string /* ignored for example */) {
|
||||
Catch::Generators::GeneratorWrapper<std::string>
|
||||
lines( std::string const& lines ) {
|
||||
return Catch::Generators::GeneratorWrapper<std::string>(
|
||||
new LineGenerator()
|
||||
);
|
||||
new LineGenerator( lines ) );
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
TEST_CASE("filter can convert types inside the generator expression", "[example][generator]") {
|
||||
auto num = GENERATE(map<int>([](std::string const& line) { return std::stoi(line); },
|
||||
lines("fake-file")));
|
||||
auto num = GENERATE(
|
||||
map<int>( []( std::string const& line ) { return std::stoi( line ); },
|
||||
lines( "1\n2\n3\n4\n" ) ) );
|
||||
|
||||
REQUIRE(num > 0);
|
||||
}
|
||||
|
@@ -6,8 +6,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.5.2
|
||||
// Generated: 2024-01-15 14:06:36.675713
|
||||
// Catch v3.5.3
|
||||
// Generated: 2024-03-01 22:05:56.038084
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@@ -101,8 +101,8 @@ namespace Catch {
|
||||
FDuration mean = FDuration(0);
|
||||
int i = 0;
|
||||
for (auto it = first; it < last; ++it, ++i) {
|
||||
samples.push_back(FDuration(*it));
|
||||
mean += FDuration(*it);
|
||||
samples.push_back(*it);
|
||||
mean += *it;
|
||||
}
|
||||
mean /= i;
|
||||
|
||||
@@ -558,7 +558,7 @@ bool marginComparison(double lhs, double rhs, double margin) {
|
||||
namespace Catch {
|
||||
|
||||
Approx::Approx ( double value )
|
||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100. ),
|
||||
: m_epsilon( static_cast<double>(std::numeric_limits<float>::epsilon())*100. ),
|
||||
m_margin( 0.0 ),
|
||||
m_scale( 0.0 ),
|
||||
m_value( value )
|
||||
@@ -1038,6 +1038,7 @@ namespace Catch {
|
||||
m_messages.back().message += " := ";
|
||||
start = pos;
|
||||
}
|
||||
default:; // noop
|
||||
}
|
||||
}
|
||||
assert(openings.empty() && "Mismatched openings");
|
||||
@@ -1581,8 +1582,10 @@ namespace Catch {
|
||||
while (lastDot > 0 && filename[lastDot - 1] != '.') {
|
||||
--lastDot;
|
||||
}
|
||||
--lastDot;
|
||||
// In theory we could have filename without any extension in it
|
||||
if ( lastDot == 0 ) { return StringRef(); }
|
||||
|
||||
--lastDot;
|
||||
size_t nameStart = lastDot;
|
||||
while (nameStart > 0 && filename[nameStart - 1] != '/' && filename[nameStart - 1] != '\\') {
|
||||
--nameStart;
|
||||
@@ -1966,13 +1969,13 @@ namespace Detail {
|
||||
}
|
||||
} // end unnamed namespace
|
||||
|
||||
std::string convertIntoString(StringRef string, bool escape_invisibles) {
|
||||
std::string convertIntoString(StringRef string, bool escapeInvisibles) {
|
||||
std::string ret;
|
||||
// This is enough for the "don't escape invisibles" case, and a good
|
||||
// lower bound on the "escape invisibles" case.
|
||||
ret.reserve(string.size() + 2);
|
||||
|
||||
if (!escape_invisibles) {
|
||||
if (!escapeInvisibles) {
|
||||
ret += '"';
|
||||
ret += string;
|
||||
ret += '"';
|
||||
@@ -2050,7 +2053,7 @@ std::string StringMaker<char const*>::convert(char const* str) {
|
||||
return{ "{null string}" };
|
||||
}
|
||||
}
|
||||
std::string StringMaker<char*>::convert(char* str) {
|
||||
std::string StringMaker<char*>::convert(char* str) { // NOLINT(readability-non-const-parameter)
|
||||
if (str) {
|
||||
return Detail::convertIntoString( str );
|
||||
} else {
|
||||
@@ -2147,8 +2150,8 @@ std::string StringMaker<signed char>::convert(signed char value) {
|
||||
std::string StringMaker<char>::convert(char c) {
|
||||
return ::Catch::Detail::stringify(static_cast<signed char>(c));
|
||||
}
|
||||
std::string StringMaker<unsigned char>::convert(unsigned char c) {
|
||||
return ::Catch::Detail::stringify(static_cast<char>(c));
|
||||
std::string StringMaker<unsigned char>::convert(unsigned char value) {
|
||||
return ::Catch::Detail::stringify(static_cast<char>(value));
|
||||
}
|
||||
|
||||
int StringMaker<float>::precision = 5;
|
||||
@@ -2268,7 +2271,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 5, 2, "", 0 );
|
||||
static Version version( 3, 5, 3, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -3092,7 +3095,7 @@ namespace Catch {
|
||||
line = trim(line);
|
||||
if( !line.empty() && !startsWith( line, '#' ) ) {
|
||||
if( !startsWith( line, '"' ) )
|
||||
line = '"' + line + '"';
|
||||
line = '"' + CATCH_MOVE(line) + '"';
|
||||
config.testsOrTags.push_back( line );
|
||||
config.testsOrTags.emplace_back( "," );
|
||||
}
|
||||
@@ -3573,21 +3576,21 @@ namespace {
|
||||
|
||||
namespace Catch {
|
||||
|
||||
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode implSelection,
|
||||
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
|
||||
IStream* stream ) {
|
||||
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
|
||||
if ( implSelection == ColourMode::Win32 ) {
|
||||
if ( colourSelection == ColourMode::Win32 ) {
|
||||
return Detail::make_unique<Win32ColourImpl>( stream );
|
||||
}
|
||||
#endif
|
||||
if ( implSelection == ColourMode::ANSI ) {
|
||||
if ( colourSelection == ColourMode::ANSI ) {
|
||||
return Detail::make_unique<ANSIColourImpl>( stream );
|
||||
}
|
||||
if ( implSelection == ColourMode::None ) {
|
||||
if ( colourSelection == ColourMode::None ) {
|
||||
return Detail::make_unique<NoColourImpl>( stream );
|
||||
}
|
||||
|
||||
if ( implSelection == ColourMode::PlatformDefault) {
|
||||
if ( colourSelection == ColourMode::PlatformDefault) {
|
||||
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
|
||||
if ( Win32ColourImpl::useImplementationForStream( *stream ) ) {
|
||||
return Detail::make_unique<Win32ColourImpl>( stream );
|
||||
@@ -3599,7 +3602,7 @@ namespace Catch {
|
||||
return Detail::make_unique<NoColourImpl>( stream );
|
||||
}
|
||||
|
||||
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(implSelection) );
|
||||
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(colourSelection) );
|
||||
}
|
||||
|
||||
bool isColourImplAvailable( ColourMode colourSelection ) {
|
||||
@@ -3807,7 +3810,12 @@ namespace Catch {
|
||||
|
||||
namespace Catch {
|
||||
|
||||
ITransientExpression::~ITransientExpression() = default;
|
||||
void ITransientExpression::streamReconstructedExpression(
|
||||
std::ostream& os ) const {
|
||||
// We can't make this function pure virtual to keep ITransientExpression
|
||||
// constexpr, so we write error message instead
|
||||
os << "Some class derived from ITransientExpression without overriding streamReconstructedExpression";
|
||||
}
|
||||
|
||||
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
|
||||
if( lhs.size() + rhs.size() < 40 &&
|
||||
@@ -4473,7 +4481,7 @@ namespace Catch {
|
||||
m_os{ os }, m_indent_level{ indent_level } {
|
||||
m_os << '{';
|
||||
}
|
||||
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ):
|
||||
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ) noexcept:
|
||||
m_os{ source.m_os },
|
||||
m_indent_level{ source.m_indent_level },
|
||||
m_should_comma{ source.m_should_comma },
|
||||
@@ -4504,7 +4512,7 @@ namespace Catch {
|
||||
m_os{ os }, m_indent_level{ indent_level } {
|
||||
m_os << '[';
|
||||
}
|
||||
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ):
|
||||
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ) noexcept:
|
||||
m_os{ source.m_os },
|
||||
m_indent_level{ source.m_indent_level },
|
||||
m_should_comma{ source.m_should_comma },
|
||||
@@ -5283,7 +5291,7 @@ namespace Catch {
|
||||
auto kv = splitKVPair( parts[i] );
|
||||
auto key = kv.key, value = kv.value;
|
||||
|
||||
if ( key.empty() || value.empty() ) {
|
||||
if ( key.empty() || value.empty() ) { // NOLINT(bugprone-branch-clone)
|
||||
return {};
|
||||
} else if ( key[0] == 'X' ) {
|
||||
// This is a reporter-specific option, we don't check these
|
||||
@@ -6297,17 +6305,29 @@ namespace Catch {
|
||||
}
|
||||
|
||||
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
|
||||
bool replaced = false;
|
||||
std::size_t i = str.find( replaceThis );
|
||||
while( i != std::string::npos ) {
|
||||
replaced = true;
|
||||
str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
|
||||
if( i < str.size()-withThis.size() )
|
||||
i = str.find( replaceThis, i+withThis.size() );
|
||||
if (i == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
std::size_t copyBegin = 0;
|
||||
std::string origStr = CATCH_MOVE(str);
|
||||
str.clear();
|
||||
// There is at least one replacement, so reserve with the best guess
|
||||
// we can make without actually counting the number of occurences.
|
||||
str.reserve(origStr.size() - replaceThis.size() + withThis.size());
|
||||
do {
|
||||
str.append(origStr, copyBegin, i-copyBegin );
|
||||
str += withThis;
|
||||
copyBegin = i + replaceThis.size();
|
||||
if( copyBegin < origStr.size() )
|
||||
i = origStr.find( replaceThis, copyBegin );
|
||||
else
|
||||
i = std::string::npos;
|
||||
} while( i != std::string::npos );
|
||||
if ( copyBegin < origStr.size() ) {
|
||||
str.append(origStr, copyBegin, origStr.size() );
|
||||
}
|
||||
return replaced;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
|
||||
@@ -9099,8 +9119,8 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
|
||||
m_stream << '\n' << std::flush;
|
||||
StreamingReporterBase::testRunEnded(_testRunStats);
|
||||
}
|
||||
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
|
||||
StreamingReporterBase::testRunStarting(_testInfo);
|
||||
void ConsoleReporter::testRunStarting(TestRunInfo const& _testRunInfo) {
|
||||
StreamingReporterBase::testRunStarting(_testRunInfo);
|
||||
if ( m_config->testSpec().hasFilters() ) {
|
||||
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
|
||||
<< m_config->testSpec() << '\n';
|
||||
@@ -9253,8 +9273,7 @@ namespace Catch {
|
||||
namespace {
|
||||
struct BySectionInfo {
|
||||
BySectionInfo( SectionInfo const& other ): m_other( other ) {}
|
||||
BySectionInfo( BySectionInfo const& other ):
|
||||
m_other( other.m_other ) {}
|
||||
BySectionInfo( BySectionInfo const& other ) = default;
|
||||
bool operator()(
|
||||
Detail::unique_ptr<CumulativeReporterBase::SectionNode> const&
|
||||
node ) const {
|
||||
@@ -9879,8 +9898,8 @@ namespace Catch {
|
||||
return "Outputs listings as JSON. Test listing is Work-in-Progress!";
|
||||
}
|
||||
|
||||
void JsonReporter::testRunStarting( TestRunInfo const& testInfo ) {
|
||||
StreamingReporterBase::testRunStarting( testInfo );
|
||||
void JsonReporter::testRunStarting( TestRunInfo const& runInfo ) {
|
||||
StreamingReporterBase::testRunStarting( runInfo );
|
||||
endListing();
|
||||
|
||||
assert( isInside( Writer::Object ) );
|
||||
@@ -10178,7 +10197,7 @@ namespace Catch {
|
||||
|
||||
static void normalizeNamespaceMarkers(std::string& str) {
|
||||
std::size_t pos = str.find( "::" );
|
||||
while ( pos != str.npos ) {
|
||||
while ( pos != std::string::npos ) {
|
||||
str.replace( pos, 2, "." );
|
||||
pos += 1;
|
||||
pos = str.find( "::", pos );
|
||||
|
@@ -6,8 +6,8 @@
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
// Catch v3.5.2
|
||||
// Generated: 2024-01-15 14:06:34.036475
|
||||
// Catch v3.5.3
|
||||
// Generated: 2024-03-01 22:05:55.031514
|
||||
// ----------------------------------------------------------
|
||||
// This file is an amalgamation of multiple different files.
|
||||
// You probably shouldn't edit it directly.
|
||||
@@ -114,14 +114,14 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
# define CATCH_CPP14_OR_GREATER
|
||||
# endif
|
||||
|
||||
# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
# define CATCH_CPP17_OR_GREATER
|
||||
# endif
|
||||
|
||||
# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||
# define CATCH_CPP20_OR_GREATER
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
// Only GCC compiler should be used in this block, so other compilers trying to
|
||||
@@ -762,8 +762,8 @@ namespace Catch {
|
||||
constexpr const_iterator end() const { return m_start + m_size; }
|
||||
|
||||
|
||||
friend std::string& operator += (std::string& lhs, StringRef sr);
|
||||
friend std::ostream& operator << (std::ostream& os, StringRef sr);
|
||||
friend std::string& operator += (std::string& lhs, StringRef rhs);
|
||||
friend std::ostream& operator << (std::ostream& os, StringRef str);
|
||||
friend std::string operator+(StringRef lhs, StringRef rhs);
|
||||
|
||||
/**
|
||||
@@ -2696,11 +2696,11 @@ namespace Catch {
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<signed char> {
|
||||
static std::string convert(signed char c);
|
||||
static std::string convert(signed char value);
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<unsigned char> {
|
||||
static std::string convert(unsigned char c);
|
||||
static std::string convert(unsigned char value);
|
||||
};
|
||||
|
||||
template<>
|
||||
@@ -5147,6 +5147,86 @@ namespace Detail {
|
||||
#include <type_traits>
|
||||
#include <iosfwd>
|
||||
|
||||
/** \file
|
||||
* Why does decomposing look the way it does:
|
||||
*
|
||||
* Conceptually, decomposing is simple. We change `REQUIRE( a == b )` into
|
||||
* `Decomposer{} <= a == b`, so that `Decomposer{} <= a` is evaluated first,
|
||||
* and our custom operator is used for `a == b`, because `a` is transformed
|
||||
* into `ExprLhs<T&>` and then into `BinaryExpr<T&, U&>`.
|
||||
*
|
||||
* In practice, decomposing ends up a mess, because we have to support
|
||||
* various fun things.
|
||||
*
|
||||
* 1) Types that are only comparable with literal 0, and they do this by
|
||||
* comparing against a magic type with pointer constructor and deleted
|
||||
* other constructors. Example: `REQUIRE((a <=> b) == 0)` in libstdc++
|
||||
*
|
||||
* 2) Types that are only comparable with literal 0, and they do this by
|
||||
* comparing against a magic type with consteval integer constructor.
|
||||
* Example: `REQUIRE((a <=> b) == 0)` in current MSVC STL.
|
||||
*
|
||||
* 3) Types that have no linkage, and so we cannot form a reference to
|
||||
* them. Example: some implementations of traits.
|
||||
*
|
||||
* 4) Starting with C++20, when the compiler sees `a == b`, it also uses
|
||||
* `b == a` when constructing the overload set. For us this means that
|
||||
* when the compiler handles `ExprLhs<T> == b`, it also tries to resolve
|
||||
* the overload set for `b == ExprLhs<T>`.
|
||||
*
|
||||
* To accomodate these use cases, decomposer ended up rather complex.
|
||||
*
|
||||
* 1) These types are handled by adding SFINAE overloads to our comparison
|
||||
* operators, checking whether `T == U` are comparable with the given
|
||||
* operator, and if not, whether T (or U) are comparable with literal 0.
|
||||
* If yes, the overload compares T (or U) with 0 literal inline in the
|
||||
* definition.
|
||||
*
|
||||
* Note that for extra correctness, we check that the other type is
|
||||
* either an `int` (literal 0 is captured as `int` by templates), or
|
||||
* a `long` (some platforms use 0L for `NULL` and we want to support
|
||||
* that for pointer comparisons).
|
||||
*
|
||||
* 2) For these types, `is_foo_comparable<T, int>` is true, but letting
|
||||
* them fall into the overload that actually does `T == int` causes
|
||||
* compilation error. Handling them requires that the decomposition
|
||||
* is `constexpr`, so that P2564R3 applies and the `consteval` from
|
||||
* their accompanying magic type is propagated through the `constexpr`
|
||||
* call stack.
|
||||
*
|
||||
* However this is not enough to handle these types automatically,
|
||||
* because our default is to capture types by reference, to avoid
|
||||
* runtime copies. While these references cannot become dangling,
|
||||
* they outlive the constexpr context and thus the default capture
|
||||
* path cannot be actually constexpr.
|
||||
*
|
||||
* The solution is to capture these types by value, by explicitly
|
||||
* specializing `Catch::capture_by_value` for them. Catch2 provides
|
||||
* specialization for `std::foo_ordering`s, but users can specialize
|
||||
* the trait for their own types as well.
|
||||
*
|
||||
* 3) If a type has no linkage, we also cannot capture it by reference.
|
||||
* The solution is once again to capture them by value. We handle
|
||||
* the common cases by using `std::is_arithmetic` as the default
|
||||
* for `Catch::capture_by_value`, but that is only a some-effort
|
||||
* heuristic. But as with 2), users can specialize `capture_by_value`
|
||||
* for their own types as needed.
|
||||
*
|
||||
* 4) To support C++20 and make the SFINAE on our decomposing operators
|
||||
* work, the SFINAE has to happen in return type, rather than in
|
||||
* a template type. This is due to our use of logical type traits
|
||||
* (`conjunction`/`disjunction`/`negation`), that we use to workaround
|
||||
* an issue in older (9-) versions of GCC. I still blame C++20 for
|
||||
* this, because without the comparison order switching, the logical
|
||||
* traits could still be used in template type.
|
||||
*
|
||||
* There are also other side concerns, e.g. supporting both `REQUIRE(a)`
|
||||
* and `REQUIRE(a == b)`, or making `REQUIRE_THAT(a, IsEqual(b))` slot
|
||||
* nicely into the same expression handling logic, but these are rather
|
||||
* straightforward and add only a bit of complexity (e.g. common base
|
||||
* class for decomposed expressions).
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
|
||||
@@ -5164,8 +5244,33 @@ namespace Detail {
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
#if defined(CATCH_CPP20_OR_GREATER) && __has_include(<compare>)
|
||||
# include <compare>
|
||||
# if defined( __cpp_lib_three_way_comparison ) && \
|
||||
__cpp_lib_three_way_comparison >= 201907L
|
||||
# define CATCH_CONFIG_CPP20_COMPARE_OVERLOADS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
// Note: There is nothing that stops us from extending this,
|
||||
// e.g. to `std::is_scalar`, but the more encompassing
|
||||
// traits are usually also more expensive. For now we
|
||||
// keep this as it used to be and it can be changed later.
|
||||
template <typename T>
|
||||
struct capture_by_value
|
||||
: std::integral_constant<bool, std::is_arithmetic<T>{}> {};
|
||||
|
||||
#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS )
|
||||
template <>
|
||||
struct capture_by_value<std::strong_ordering> : std::true_type {};
|
||||
template <>
|
||||
struct capture_by_value<std::weak_ordering> : std::true_type {};
|
||||
template <>
|
||||
struct capture_by_value<std::partial_ordering> : std::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct always_false : std::false_type {};
|
||||
|
||||
@@ -5174,11 +5279,12 @@ namespace Catch {
|
||||
bool m_result;
|
||||
|
||||
public:
|
||||
auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
|
||||
auto getResult() const -> bool { return m_result; }
|
||||
virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
|
||||
constexpr auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
|
||||
constexpr auto getResult() const -> bool { return m_result; }
|
||||
//! This function **has** to be overriden by the derived class.
|
||||
virtual void streamReconstructedExpression( std::ostream& os ) const;
|
||||
|
||||
ITransientExpression( bool isBinaryExpression, bool result )
|
||||
constexpr ITransientExpression( bool isBinaryExpression, bool result )
|
||||
: m_isBinaryExpression( isBinaryExpression ),
|
||||
m_result( result )
|
||||
{}
|
||||
@@ -5189,7 +5295,7 @@ namespace Catch {
|
||||
|
||||
// We don't actually need a virtual destructor, but many static analysers
|
||||
// complain if it's not here :-(
|
||||
virtual ~ITransientExpression(); // = default;
|
||||
virtual ~ITransientExpression() = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
|
||||
expr.streamReconstructedExpression(out);
|
||||
@@ -5211,7 +5317,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
public:
|
||||
BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
|
||||
constexpr BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
|
||||
: ITransientExpression{ true, comparisonResult },
|
||||
m_lhs( lhs ),
|
||||
m_op( op ),
|
||||
@@ -5284,7 +5390,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
public:
|
||||
explicit UnaryExpr( LhsT lhs )
|
||||
explicit constexpr UnaryExpr( LhsT lhs )
|
||||
: ITransientExpression{ false, static_cast<bool>(lhs) },
|
||||
m_lhs( lhs )
|
||||
{}
|
||||
@@ -5295,30 +5401,30 @@ namespace Catch {
|
||||
class ExprLhs {
|
||||
LhsT m_lhs;
|
||||
public:
|
||||
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||
explicit constexpr ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
Detail::negation<capture_by_value< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
capture_by_value<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -5332,7 +5438,7 @@ namespace Catch {
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -5350,28 +5456,29 @@ namespace Catch {
|
||||
|
||||
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
|
||||
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
Detail::negation<capture_by_value< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
capture_by_value<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -5383,7 +5490,7 @@ namespace Catch {
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -5404,16 +5511,16 @@ namespace Catch {
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||
!capture_by_value<std::remove_reference_t<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t<std::is_arithmetic<RhsT>::value, \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t<capture_by_value<RhsT>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
@@ -5439,19 +5546,23 @@ namespace Catch {
|
||||
"wrap the expression inside parentheses, or decompose it");
|
||||
}
|
||||
|
||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||
constexpr auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||
return UnaryExpr<LhsT>{ m_lhs };
|
||||
}
|
||||
};
|
||||
|
||||
struct Decomposer {
|
||||
template<typename T, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<T>>::value, int> = 0>
|
||||
friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
!capture_by_value<std::remove_reference_t<T>>::value,
|
||||
int> = 0>
|
||||
constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
|
||||
return ExprLhs<const T&>{ lhs };
|
||||
}
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
|
||||
friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
|
||||
template <typename T,
|
||||
std::enable_if_t<capture_by_value<T>::value, int> = 0>
|
||||
constexpr friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
|
||||
return ExprLhs<T>{ value };
|
||||
}
|
||||
};
|
||||
@@ -5571,7 +5682,7 @@ namespace Catch {
|
||||
INTERNAL_CATCH_TRY { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
|
||||
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); /* NOLINT(bugprone-chained-comparison) */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
||||
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
||||
@@ -5786,7 +5897,9 @@ namespace Catch {
|
||||
namespace Detail {
|
||||
// Intentionally without linkage, as it should only be used as a dummy
|
||||
// symbol for static analysis.
|
||||
int GetNewSectionHint();
|
||||
// The arguments are used as a dummy for checking warnings in the passed
|
||||
// expressions.
|
||||
int GetNewSectionHint( StringRef, const char* const = nullptr );
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
@@ -5797,7 +5910,8 @@ namespace Catch {
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalSectionHint = \
|
||||
Catch::Detail::GetNewSectionHint(__VA_ARGS__); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
@@ -5807,7 +5921,8 @@ namespace Catch {
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint( \
|
||||
( Catch::ReusableStringStream() << __VA_ARGS__ ).str()); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
@@ -5929,7 +6044,7 @@ struct AutoReg : Detail::NonCopyable {
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
struct DummyUse {
|
||||
DummyUse( void ( * )( int ) );
|
||||
DummyUse( void ( * )( int ), Catch::NameAndTags const& );
|
||||
};
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
@@ -5941,18 +6056,18 @@ namespace Catch {
|
||||
// tests can compile. The redefined `TEST_CASE` shadows this with param.
|
||||
static int catchInternalSectionHint = 0;
|
||||
|
||||
# define INTERNAL_CATCH_TESTCASE2( fname ) \
|
||||
# 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) ); \
|
||||
dummyUser )( &(fname), Catch::NameAndTags{ __VA_ARGS__ } ); \
|
||||
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 ) )
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( dummyFunction ), __VA_ARGS__ )
|
||||
|
||||
|
||||
#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
@@ -6935,7 +7050,7 @@ namespace Catch {
|
||||
struct TestCaseInfo : Detail::NonCopyable {
|
||||
|
||||
TestCaseInfo(StringRef _className,
|
||||
NameAndTags const& _tags,
|
||||
NameAndTags const& _nameAndTags,
|
||||
SourceLineInfo const& _lineInfo);
|
||||
|
||||
bool isHidden() const;
|
||||
@@ -7148,7 +7263,7 @@ namespace Catch {
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 5
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 3
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
||||
@@ -7847,9 +7962,8 @@ namespace Catch {
|
||||
struct ExtendedMultResult {
|
||||
T upper;
|
||||
T lower;
|
||||
friend bool operator==( ExtendedMultResult const& lhs,
|
||||
ExtendedMultResult const& rhs ) {
|
||||
return lhs.upper == rhs.upper && lhs.lower == rhs.lower;
|
||||
bool operator==( ExtendedMultResult const& rhs ) const {
|
||||
return upper == rhs.upper && lower == rhs.lower;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9322,7 +9436,7 @@ namespace Catch {
|
||||
|
||||
std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
|
||||
|
||||
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
|
||||
EnumInfo const& registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values) override;
|
||||
};
|
||||
|
||||
std::vector<StringRef> parseEnums( StringRef enums );
|
||||
@@ -9795,7 +9909,7 @@ namespace Catch {
|
||||
JsonObjectWriter( std::ostream& os );
|
||||
JsonObjectWriter( std::ostream& os, std::uint64_t indent_level );
|
||||
|
||||
JsonObjectWriter( JsonObjectWriter&& source );
|
||||
JsonObjectWriter( JsonObjectWriter&& source ) noexcept;
|
||||
JsonObjectWriter& operator=( JsonObjectWriter&& source ) = delete;
|
||||
|
||||
~JsonObjectWriter();
|
||||
@@ -9814,7 +9928,7 @@ namespace Catch {
|
||||
JsonArrayWriter( std::ostream& os );
|
||||
JsonArrayWriter( std::ostream& os, std::uint64_t indent_level );
|
||||
|
||||
JsonArrayWriter( JsonArrayWriter&& source );
|
||||
JsonArrayWriter( JsonArrayWriter&& source ) noexcept;
|
||||
JsonArrayWriter& operator=( JsonArrayWriter&& source ) = delete;
|
||||
|
||||
~JsonArrayWriter();
|
||||
@@ -13454,7 +13568,7 @@ namespace Catch {
|
||||
|
||||
void assertionEnded( AssertionStats const& assertionStats ) override;
|
||||
void sectionEnded( SectionStats const& sectionStats ) override;
|
||||
void testCasePartialEnded(TestCaseStats const& testInfo, uint64_t partNumber) override;
|
||||
void testCasePartialEnded(TestCaseStats const& testStats, uint64_t partNumber) override;
|
||||
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
|
||||
void testRunEnded( TestRunStats const& testRunStats ) override;
|
||||
|
||||
@@ -13622,7 +13736,7 @@ namespace Catch {
|
||||
xml.endElement();
|
||||
}
|
||||
|
||||
void writeRun( TestRunNode const& groupNode );
|
||||
void writeRun( TestRunNode const& runNode );
|
||||
|
||||
void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes);
|
||||
|
||||
@@ -13707,8 +13821,8 @@ namespace Catch {
|
||||
return "Reports test results as TeamCity service messages"s;
|
||||
}
|
||||
|
||||
void testRunStarting( TestRunInfo const& groupInfo ) override;
|
||||
void testRunEnded( TestRunStats const& testGroupStats ) override;
|
||||
void testRunStarting( TestRunInfo const& runInfo ) override;
|
||||
void testRunEnded( TestRunStats const& runStats ) override;
|
||||
|
||||
|
||||
void assertionEnded(AssertionStats const& assertionStats) override;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
project(
|
||||
'catch2',
|
||||
'cpp',
|
||||
version: '3.5.2', # CML version placeholder, don't delete
|
||||
version: '3.5.3', # CML version placeholder, don't delete
|
||||
license: 'BSL-1.0',
|
||||
meson_version: '>=0.54.1',
|
||||
)
|
||||
|
@@ -354,7 +354,7 @@ endif()
|
||||
add_library(Catch2::Catch2 ALIAS Catch2)
|
||||
|
||||
if (ANDROID)
|
||||
target_link_libraries(Catch2 INTERFACE log)
|
||||
target_link_libraries(Catch2 PRIVATE log)
|
||||
endif()
|
||||
|
||||
set_target_properties(Catch2 PROPERTIES
|
||||
|
@@ -63,8 +63,8 @@ namespace Catch {
|
||||
FDuration mean = FDuration(0);
|
||||
int i = 0;
|
||||
for (auto it = first; it < last; ++it, ++i) {
|
||||
samples.push_back(FDuration(*it));
|
||||
mean += FDuration(*it);
|
||||
samples.push_back(*it);
|
||||
mean += *it;
|
||||
}
|
||||
mean /= i;
|
||||
|
||||
|
@@ -25,7 +25,7 @@ bool marginComparison(double lhs, double rhs, double margin) {
|
||||
namespace Catch {
|
||||
|
||||
Approx::Approx ( double value )
|
||||
: m_epsilon( std::numeric_limits<float>::epsilon()*100. ),
|
||||
: m_epsilon( static_cast<double>(std::numeric_limits<float>::epsilon())*100. ),
|
||||
m_margin( 0.0 ),
|
||||
m_scale( 0.0 ),
|
||||
m_value( value )
|
||||
|
@@ -91,6 +91,7 @@ namespace Catch {
|
||||
m_messages.back().message += " := ";
|
||||
start = pos;
|
||||
}
|
||||
default:; // noop
|
||||
}
|
||||
}
|
||||
assert(openings.empty() && "Mismatched openings");
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include <catch2/internal/catch_noncopyable.hpp>
|
||||
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_reporter_registry.hpp>
|
||||
|
||||
#include <exception>
|
||||
|
||||
|
@@ -85,8 +85,10 @@ namespace Catch {
|
||||
while (lastDot > 0 && filename[lastDot - 1] != '.') {
|
||||
--lastDot;
|
||||
}
|
||||
--lastDot;
|
||||
// In theory we could have filename without any extension in it
|
||||
if ( lastDot == 0 ) { return StringRef(); }
|
||||
|
||||
--lastDot;
|
||||
size_t nameStart = lastDot;
|
||||
while (nameStart > 0 && filename[nameStart - 1] != '/' && filename[nameStart - 1] != '\\') {
|
||||
--nameStart;
|
||||
|
@@ -68,7 +68,7 @@ namespace Catch {
|
||||
struct TestCaseInfo : Detail::NonCopyable {
|
||||
|
||||
TestCaseInfo(StringRef _className,
|
||||
NameAndTags const& _tags,
|
||||
NameAndTags const& _nameAndTags,
|
||||
SourceLineInfo const& _lineInfo);
|
||||
|
||||
bool isHidden() const;
|
||||
|
@@ -54,13 +54,13 @@ namespace Detail {
|
||||
}
|
||||
} // end unnamed namespace
|
||||
|
||||
std::string convertIntoString(StringRef string, bool escape_invisibles) {
|
||||
std::string convertIntoString(StringRef string, bool escapeInvisibles) {
|
||||
std::string ret;
|
||||
// This is enough for the "don't escape invisibles" case, and a good
|
||||
// lower bound on the "escape invisibles" case.
|
||||
ret.reserve(string.size() + 2);
|
||||
|
||||
if (!escape_invisibles) {
|
||||
if (!escapeInvisibles) {
|
||||
ret += '"';
|
||||
ret += string;
|
||||
ret += '"';
|
||||
@@ -138,7 +138,7 @@ std::string StringMaker<char const*>::convert(char const* str) {
|
||||
return{ "{null string}" };
|
||||
}
|
||||
}
|
||||
std::string StringMaker<char*>::convert(char* str) {
|
||||
std::string StringMaker<char*>::convert(char* str) { // NOLINT(readability-non-const-parameter)
|
||||
if (str) {
|
||||
return Detail::convertIntoString( str );
|
||||
} else {
|
||||
@@ -235,8 +235,8 @@ std::string StringMaker<signed char>::convert(signed char value) {
|
||||
std::string StringMaker<char>::convert(char c) {
|
||||
return ::Catch::Detail::stringify(static_cast<signed char>(c));
|
||||
}
|
||||
std::string StringMaker<unsigned char>::convert(unsigned char c) {
|
||||
return ::Catch::Detail::stringify(static_cast<char>(c));
|
||||
std::string StringMaker<unsigned char>::convert(unsigned char value) {
|
||||
return ::Catch::Detail::stringify(static_cast<char>(value));
|
||||
}
|
||||
|
||||
int StringMaker<float>::precision = 5;
|
||||
|
@@ -279,11 +279,11 @@ namespace Catch {
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<signed char> {
|
||||
static std::string convert(signed char c);
|
||||
static std::string convert(signed char value);
|
||||
};
|
||||
template<>
|
||||
struct StringMaker<unsigned char> {
|
||||
static std::string convert(unsigned char c);
|
||||
static std::string convert(unsigned char value);
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@@ -36,7 +36,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 3, 5, 2, "", 0 );
|
||||
static Version version( 3, 5, 3, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,6 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 3
|
||||
#define CATCH_VERSION_MINOR 5
|
||||
#define CATCH_VERSION_PATCH 2
|
||||
#define CATCH_VERSION_PATCH 3
|
||||
|
||||
#endif // CATCH_VERSION_MACROS_HPP_INCLUDED
|
||||
|
@@ -47,7 +47,7 @@ namespace Catch {
|
||||
line = trim(line);
|
||||
if( !line.empty() && !startsWith( line, '#' ) ) {
|
||||
if( !startsWith( line, '"' ) )
|
||||
line = '"' + line + '"';
|
||||
line = '"' + CATCH_MOVE(line) + '"';
|
||||
config.testsOrTags.push_back( line );
|
||||
config.testsOrTags.emplace_back( "," );
|
||||
}
|
||||
|
@@ -29,14 +29,14 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
|
||||
# define CATCH_CPP14_OR_GREATER
|
||||
# endif
|
||||
|
||||
# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
# define CATCH_CPP17_OR_GREATER
|
||||
# endif
|
||||
|
||||
# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
|
||||
# define CATCH_CPP20_OR_GREATER
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
// Only GCC compiler should be used in this block, so other compilers trying to
|
||||
|
@@ -230,21 +230,21 @@ namespace {
|
||||
|
||||
namespace Catch {
|
||||
|
||||
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode implSelection,
|
||||
Detail::unique_ptr<ColourImpl> makeColourImpl( ColourMode colourSelection,
|
||||
IStream* stream ) {
|
||||
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
|
||||
if ( implSelection == ColourMode::Win32 ) {
|
||||
if ( colourSelection == ColourMode::Win32 ) {
|
||||
return Detail::make_unique<Win32ColourImpl>( stream );
|
||||
}
|
||||
#endif
|
||||
if ( implSelection == ColourMode::ANSI ) {
|
||||
if ( colourSelection == ColourMode::ANSI ) {
|
||||
return Detail::make_unique<ANSIColourImpl>( stream );
|
||||
}
|
||||
if ( implSelection == ColourMode::None ) {
|
||||
if ( colourSelection == ColourMode::None ) {
|
||||
return Detail::make_unique<NoColourImpl>( stream );
|
||||
}
|
||||
|
||||
if ( implSelection == ColourMode::PlatformDefault) {
|
||||
if ( colourSelection == ColourMode::PlatformDefault) {
|
||||
#if defined( CATCH_CONFIG_COLOUR_WIN32 )
|
||||
if ( Win32ColourImpl::useImplementationForStream( *stream ) ) {
|
||||
return Detail::make_unique<Win32ColourImpl>( stream );
|
||||
@@ -256,7 +256,7 @@ namespace Catch {
|
||||
return Detail::make_unique<NoColourImpl>( stream );
|
||||
}
|
||||
|
||||
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(implSelection) );
|
||||
CATCH_ERROR( "Could not create colour impl for selection " << static_cast<int>(colourSelection) );
|
||||
}
|
||||
|
||||
bool isColourImplAvailable( ColourMode colourSelection ) {
|
||||
|
@@ -10,7 +10,12 @@
|
||||
|
||||
namespace Catch {
|
||||
|
||||
ITransientExpression::~ITransientExpression() = default;
|
||||
void ITransientExpression::streamReconstructedExpression(
|
||||
std::ostream& os ) const {
|
||||
// We can't make this function pure virtual to keep ITransientExpression
|
||||
// constexpr, so we write error message instead
|
||||
os << "Some class derived from ITransientExpression without overriding streamReconstructedExpression";
|
||||
}
|
||||
|
||||
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {
|
||||
if( lhs.size() + rhs.size() < 40 &&
|
||||
|
@@ -13,10 +13,91 @@
|
||||
#include <catch2/internal/catch_compare_traits.hpp>
|
||||
#include <catch2/internal/catch_test_failure_exception.hpp>
|
||||
#include <catch2/internal/catch_logical_traits.hpp>
|
||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <iosfwd>
|
||||
|
||||
/** \file
|
||||
* Why does decomposing look the way it does:
|
||||
*
|
||||
* Conceptually, decomposing is simple. We change `REQUIRE( a == b )` into
|
||||
* `Decomposer{} <= a == b`, so that `Decomposer{} <= a` is evaluated first,
|
||||
* and our custom operator is used for `a == b`, because `a` is transformed
|
||||
* into `ExprLhs<T&>` and then into `BinaryExpr<T&, U&>`.
|
||||
*
|
||||
* In practice, decomposing ends up a mess, because we have to support
|
||||
* various fun things.
|
||||
*
|
||||
* 1) Types that are only comparable with literal 0, and they do this by
|
||||
* comparing against a magic type with pointer constructor and deleted
|
||||
* other constructors. Example: `REQUIRE((a <=> b) == 0)` in libstdc++
|
||||
*
|
||||
* 2) Types that are only comparable with literal 0, and they do this by
|
||||
* comparing against a magic type with consteval integer constructor.
|
||||
* Example: `REQUIRE((a <=> b) == 0)` in current MSVC STL.
|
||||
*
|
||||
* 3) Types that have no linkage, and so we cannot form a reference to
|
||||
* them. Example: some implementations of traits.
|
||||
*
|
||||
* 4) Starting with C++20, when the compiler sees `a == b`, it also uses
|
||||
* `b == a` when constructing the overload set. For us this means that
|
||||
* when the compiler handles `ExprLhs<T> == b`, it also tries to resolve
|
||||
* the overload set for `b == ExprLhs<T>`.
|
||||
*
|
||||
* To accomodate these use cases, decomposer ended up rather complex.
|
||||
*
|
||||
* 1) These types are handled by adding SFINAE overloads to our comparison
|
||||
* operators, checking whether `T == U` are comparable with the given
|
||||
* operator, and if not, whether T (or U) are comparable with literal 0.
|
||||
* If yes, the overload compares T (or U) with 0 literal inline in the
|
||||
* definition.
|
||||
*
|
||||
* Note that for extra correctness, we check that the other type is
|
||||
* either an `int` (literal 0 is captured as `int` by templates), or
|
||||
* a `long` (some platforms use 0L for `NULL` and we want to support
|
||||
* that for pointer comparisons).
|
||||
*
|
||||
* 2) For these types, `is_foo_comparable<T, int>` is true, but letting
|
||||
* them fall into the overload that actually does `T == int` causes
|
||||
* compilation error. Handling them requires that the decomposition
|
||||
* is `constexpr`, so that P2564R3 applies and the `consteval` from
|
||||
* their accompanying magic type is propagated through the `constexpr`
|
||||
* call stack.
|
||||
*
|
||||
* However this is not enough to handle these types automatically,
|
||||
* because our default is to capture types by reference, to avoid
|
||||
* runtime copies. While these references cannot become dangling,
|
||||
* they outlive the constexpr context and thus the default capture
|
||||
* path cannot be actually constexpr.
|
||||
*
|
||||
* The solution is to capture these types by value, by explicitly
|
||||
* specializing `Catch::capture_by_value` for them. Catch2 provides
|
||||
* specialization for `std::foo_ordering`s, but users can specialize
|
||||
* the trait for their own types as well.
|
||||
*
|
||||
* 3) If a type has no linkage, we also cannot capture it by reference.
|
||||
* The solution is once again to capture them by value. We handle
|
||||
* the common cases by using `std::is_arithmetic` as the default
|
||||
* for `Catch::capture_by_value`, but that is only a some-effort
|
||||
* heuristic. But as with 2), users can specialize `capture_by_value`
|
||||
* for their own types as needed.
|
||||
*
|
||||
* 4) To support C++20 and make the SFINAE on our decomposing operators
|
||||
* work, the SFINAE has to happen in return type, rather than in
|
||||
* a template type. This is due to our use of logical type traits
|
||||
* (`conjunction`/`disjunction`/`negation`), that we use to workaround
|
||||
* an issue in older (9-) versions of GCC. I still blame C++20 for
|
||||
* this, because without the comparison order switching, the logical
|
||||
* traits could still be used in template type.
|
||||
*
|
||||
* There are also other side concerns, e.g. supporting both `REQUIRE(a)`
|
||||
* and `REQUIRE(a == b)`, or making `REQUIRE_THAT(a, IsEqual(b))` slot
|
||||
* nicely into the same expression handling logic, but these are rather
|
||||
* straightforward and add only a bit of complexity (e.g. common base
|
||||
* class for decomposed expressions).
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
|
||||
@@ -34,8 +115,33 @@
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
#if defined(CATCH_CPP20_OR_GREATER) && __has_include(<compare>)
|
||||
# include <compare>
|
||||
# if defined( __cpp_lib_three_way_comparison ) && \
|
||||
__cpp_lib_three_way_comparison >= 201907L
|
||||
# define CATCH_CONFIG_CPP20_COMPARE_OVERLOADS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
// Note: There is nothing that stops us from extending this,
|
||||
// e.g. to `std::is_scalar`, but the more encompassing
|
||||
// traits are usually also more expensive. For now we
|
||||
// keep this as it used to be and it can be changed later.
|
||||
template <typename T>
|
||||
struct capture_by_value
|
||||
: std::integral_constant<bool, std::is_arithmetic<T>{}> {};
|
||||
|
||||
#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS )
|
||||
template <>
|
||||
struct capture_by_value<std::strong_ordering> : std::true_type {};
|
||||
template <>
|
||||
struct capture_by_value<std::weak_ordering> : std::true_type {};
|
||||
template <>
|
||||
struct capture_by_value<std::partial_ordering> : std::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct always_false : std::false_type {};
|
||||
|
||||
@@ -44,11 +150,12 @@ namespace Catch {
|
||||
bool m_result;
|
||||
|
||||
public:
|
||||
auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
|
||||
auto getResult() const -> bool { return m_result; }
|
||||
virtual void streamReconstructedExpression( std::ostream &os ) const = 0;
|
||||
constexpr auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }
|
||||
constexpr auto getResult() const -> bool { return m_result; }
|
||||
//! This function **has** to be overriden by the derived class.
|
||||
virtual void streamReconstructedExpression( std::ostream& os ) const;
|
||||
|
||||
ITransientExpression( bool isBinaryExpression, bool result )
|
||||
constexpr ITransientExpression( bool isBinaryExpression, bool result )
|
||||
: m_isBinaryExpression( isBinaryExpression ),
|
||||
m_result( result )
|
||||
{}
|
||||
@@ -57,14 +164,13 @@ namespace Catch {
|
||||
ITransientExpression(ITransientExpression const&) = default;
|
||||
ITransientExpression& operator=(ITransientExpression const&) = default;
|
||||
|
||||
// We don't actually need a virtual destructor, but many static analysers
|
||||
// complain if it's not here :-(
|
||||
virtual ~ITransientExpression(); // = default;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, ITransientExpression const& expr) {
|
||||
expr.streamReconstructedExpression(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
protected:
|
||||
~ITransientExpression() = default;
|
||||
};
|
||||
|
||||
void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );
|
||||
@@ -81,7 +187,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
public:
|
||||
BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
|
||||
constexpr BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
|
||||
: ITransientExpression{ true, comparisonResult },
|
||||
m_lhs( lhs ),
|
||||
m_op( op ),
|
||||
@@ -154,7 +260,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
public:
|
||||
explicit UnaryExpr( LhsT lhs )
|
||||
explicit constexpr UnaryExpr( LhsT lhs )
|
||||
: ITransientExpression{ false, static_cast<bool>(lhs) },
|
||||
m_lhs( lhs )
|
||||
{}
|
||||
@@ -165,30 +271,30 @@ namespace Catch {
|
||||
class ExprLhs {
|
||||
LhsT m_lhs;
|
||||
public:
|
||||
explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||
explicit constexpr ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
Detail::negation<capture_by_value< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
capture_by_value<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -202,7 +308,7 @@ namespace Catch {
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -220,28 +326,29 @@ namespace Catch {
|
||||
|
||||
#undef CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR
|
||||
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
Detail::negation<std::is_arithmetic< \
|
||||
Detail::negation<capture_by_value< \
|
||||
std::remove_reference_t<RhsT>>>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction<Detail::is_##id##_comparable<LhsT, RhsT>, \
|
||||
std::is_arithmetic<RhsT>>::value, \
|
||||
capture_by_value<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -253,7 +360,7 @@ namespace Catch {
|
||||
static_cast<bool>( lhs.m_lhs op 0 ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t< \
|
||||
Detail::conjunction< \
|
||||
Detail::negation<Detail::is_##id##_comparable<LhsT, RhsT>>, \
|
||||
@@ -274,16 +381,16 @@ namespace Catch {
|
||||
|
||||
#define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \
|
||||
->std::enable_if_t< \
|
||||
!std::is_arithmetic<std::remove_reference_t<RhsT>>::value, \
|
||||
!capture_by_value<std::remove_reference_t<RhsT>>::value, \
|
||||
BinaryExpr<LhsT, RhsT const&>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
} \
|
||||
template <typename RhsT> \
|
||||
friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t<std::is_arithmetic<RhsT>::value, \
|
||||
constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \
|
||||
->std::enable_if_t<capture_by_value<RhsT>::value, \
|
||||
BinaryExpr<LhsT, RhsT>> { \
|
||||
return { \
|
||||
static_cast<bool>( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \
|
||||
@@ -309,19 +416,23 @@ namespace Catch {
|
||||
"wrap the expression inside parentheses, or decompose it");
|
||||
}
|
||||
|
||||
auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||
constexpr auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
|
||||
return UnaryExpr<LhsT>{ m_lhs };
|
||||
}
|
||||
};
|
||||
|
||||
struct Decomposer {
|
||||
template<typename T, std::enable_if_t<!std::is_arithmetic<std::remove_reference_t<T>>::value, int> = 0>
|
||||
friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
!capture_by_value<std::remove_reference_t<T>>::value,
|
||||
int> = 0>
|
||||
constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
|
||||
return ExprLhs<const T&>{ lhs };
|
||||
}
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
|
||||
friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
|
||||
template <typename T,
|
||||
std::enable_if_t<capture_by_value<T>::value, int> = 0>
|
||||
constexpr friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
|
||||
return ExprLhs<T>{ value };
|
||||
}
|
||||
};
|
||||
|
@@ -24,7 +24,7 @@ namespace Catch {
|
||||
|
||||
std::vector<Catch::Detail::unique_ptr<EnumInfo>> m_enumInfos;
|
||||
|
||||
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
|
||||
EnumInfo const& registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values) override;
|
||||
};
|
||||
|
||||
std::vector<StringRef> parseEnums( StringRef enums );
|
||||
|
@@ -31,7 +31,7 @@ namespace Catch {
|
||||
m_os{ os }, m_indent_level{ indent_level } {
|
||||
m_os << '{';
|
||||
}
|
||||
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ):
|
||||
JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ) noexcept:
|
||||
m_os{ source.m_os },
|
||||
m_indent_level{ source.m_indent_level },
|
||||
m_should_comma{ source.m_should_comma },
|
||||
@@ -62,7 +62,7 @@ namespace Catch {
|
||||
m_os{ os }, m_indent_level{ indent_level } {
|
||||
m_os << '[';
|
||||
}
|
||||
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ):
|
||||
JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ) noexcept:
|
||||
m_os{ source.m_os },
|
||||
m_indent_level{ source.m_indent_level },
|
||||
m_should_comma{ source.m_should_comma },
|
||||
|
@@ -65,7 +65,7 @@ namespace Catch {
|
||||
JsonObjectWriter( std::ostream& os );
|
||||
JsonObjectWriter( std::ostream& os, std::uint64_t indent_level );
|
||||
|
||||
JsonObjectWriter( JsonObjectWriter&& source );
|
||||
JsonObjectWriter( JsonObjectWriter&& source ) noexcept;
|
||||
JsonObjectWriter& operator=( JsonObjectWriter&& source ) = delete;
|
||||
|
||||
~JsonObjectWriter();
|
||||
@@ -84,7 +84,7 @@ namespace Catch {
|
||||
JsonArrayWriter( std::ostream& os );
|
||||
JsonArrayWriter( std::ostream& os, std::uint64_t indent_level );
|
||||
|
||||
JsonArrayWriter( JsonArrayWriter&& source );
|
||||
JsonArrayWriter( JsonArrayWriter&& source ) noexcept;
|
||||
JsonArrayWriter& operator=( JsonArrayWriter&& source ) = delete;
|
||||
|
||||
~JsonArrayWriter();
|
||||
|
@@ -41,9 +41,8 @@ namespace Catch {
|
||||
struct ExtendedMultResult {
|
||||
T upper;
|
||||
T lower;
|
||||
friend bool operator==( ExtendedMultResult const& lhs,
|
||||
ExtendedMultResult const& rhs ) {
|
||||
return lhs.upper == rhs.upper && lhs.lower == rhs.lower;
|
||||
bool operator==( ExtendedMultResult const& rhs ) const {
|
||||
return upper == rhs.upper && lower == rhs.lower;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -117,7 +117,7 @@ namespace Catch {
|
||||
auto kv = splitKVPair( parts[i] );
|
||||
auto key = kv.key, value = kv.value;
|
||||
|
||||
if ( key.empty() || value.empty() ) {
|
||||
if ( key.empty() || value.empty() ) { // NOLINT(bugprone-branch-clone)
|
||||
return {};
|
||||
} else if ( key[0] == 'X' ) {
|
||||
// This is a reporter-specific option, we don't check these
|
||||
|
@@ -69,7 +69,9 @@ namespace Catch {
|
||||
namespace Detail {
|
||||
// Intentionally without linkage, as it should only be used as a dummy
|
||||
// symbol for static analysis.
|
||||
int GetNewSectionHint();
|
||||
// The arguments are used as a dummy for checking warnings in the passed
|
||||
// expressions.
|
||||
int GetNewSectionHint( StringRef, const char* const = nullptr );
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
@@ -80,7 +82,8 @@ namespace Catch {
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalSectionHint = \
|
||||
Catch::Detail::GetNewSectionHint(__VA_ARGS__); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
@@ -90,7 +93,8 @@ namespace Catch {
|
||||
CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
|
||||
if ( [[maybe_unused]] const int catchInternalPreviousSectionHint = \
|
||||
catchInternalSectionHint, \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint(); \
|
||||
catchInternalSectionHint = Catch::Detail::GetNewSectionHint( \
|
||||
( Catch::ReusableStringStream() << __VA_ARGS__ ).str()); \
|
||||
catchInternalPreviousSectionHint == __LINE__ ) \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
#include <catch2/internal/catch_string_manip.hpp>
|
||||
#include <catch2/internal/catch_stringref.hpp>
|
||||
|
||||
@@ -65,17 +66,29 @@ namespace Catch {
|
||||
}
|
||||
|
||||
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
|
||||
bool replaced = false;
|
||||
std::size_t i = str.find( replaceThis );
|
||||
while( i != std::string::npos ) {
|
||||
replaced = true;
|
||||
str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
|
||||
if( i < str.size()-withThis.size() )
|
||||
i = str.find( replaceThis, i+withThis.size() );
|
||||
if (i == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
std::size_t copyBegin = 0;
|
||||
std::string origStr = CATCH_MOVE(str);
|
||||
str.clear();
|
||||
// There is at least one replacement, so reserve with the best guess
|
||||
// we can make without actually counting the number of occurences.
|
||||
str.reserve(origStr.size() - replaceThis.size() + withThis.size());
|
||||
do {
|
||||
str.append(origStr, copyBegin, i-copyBegin );
|
||||
str += withThis;
|
||||
copyBegin = i + replaceThis.size();
|
||||
if( copyBegin < origStr.size() )
|
||||
i = origStr.find( replaceThis, copyBegin );
|
||||
else
|
||||
i = std::string::npos;
|
||||
} while( i != std::string::npos );
|
||||
if ( copyBegin < origStr.size() ) {
|
||||
str.append(origStr, copyBegin, origStr.size() );
|
||||
}
|
||||
return replaced;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {
|
||||
|
@@ -97,8 +97,8 @@ namespace Catch {
|
||||
constexpr const_iterator end() const { return m_start + m_size; }
|
||||
|
||||
|
||||
friend std::string& operator += (std::string& lhs, StringRef sr);
|
||||
friend std::ostream& operator << (std::ostream& os, StringRef sr);
|
||||
friend std::string& operator += (std::string& lhs, StringRef rhs);
|
||||
friend std::ostream& operator << (std::ostream& os, StringRef str);
|
||||
friend std::string operator+(StringRef lhs, StringRef rhs);
|
||||
|
||||
/**
|
||||
|
@@ -49,7 +49,7 @@
|
||||
INTERNAL_CATCH_TRY { \
|
||||
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
|
||||
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); /* NOLINT(bugprone-chained-comparison) */ \
|
||||
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
|
||||
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
|
||||
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
|
||||
|
@@ -95,7 +95,7 @@ struct AutoReg : Detail::NonCopyable {
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
struct DummyUse {
|
||||
DummyUse( void ( * )( int ) );
|
||||
DummyUse( void ( * )( int ), Catch::NameAndTags const& );
|
||||
};
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
@@ -107,18 +107,18 @@ namespace Catch {
|
||||
// tests can compile. The redefined `TEST_CASE` shadows this with param.
|
||||
static int catchInternalSectionHint = 0;
|
||||
|
||||
# define INTERNAL_CATCH_TESTCASE2( fname ) \
|
||||
# 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) ); \
|
||||
dummyUser )( &(fname), Catch::NameAndTags{ __VA_ARGS__ } ); \
|
||||
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 ) )
|
||||
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( dummyFunction ), __VA_ARGS__ )
|
||||
|
||||
|
||||
#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
|
||||
|
@@ -520,8 +520,8 @@ void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
|
||||
m_stream << '\n' << std::flush;
|
||||
StreamingReporterBase::testRunEnded(_testRunStats);
|
||||
}
|
||||
void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {
|
||||
StreamingReporterBase::testRunStarting(_testInfo);
|
||||
void ConsoleReporter::testRunStarting(TestRunInfo const& _testRunInfo) {
|
||||
StreamingReporterBase::testRunStarting(_testRunInfo);
|
||||
if ( m_config->testSpec().hasFilters() ) {
|
||||
m_stream << m_colour->guardColour( Colour::BrightYellow ) << "Filters: "
|
||||
<< m_config->testSpec() << '\n';
|
||||
|
@@ -16,8 +16,7 @@ namespace Catch {
|
||||
namespace {
|
||||
struct BySectionInfo {
|
||||
BySectionInfo( SectionInfo const& other ): m_other( other ) {}
|
||||
BySectionInfo( BySectionInfo const& other ):
|
||||
m_other( other.m_other ) {}
|
||||
BySectionInfo( BySectionInfo const& other ) = default;
|
||||
bool operator()(
|
||||
Detail::unique_ptr<CumulativeReporterBase::SectionNode> const&
|
||||
node ) const {
|
||||
|
@@ -133,8 +133,8 @@ namespace Catch {
|
||||
return "Outputs listings as JSON. Test listing is Work-in-Progress!";
|
||||
}
|
||||
|
||||
void JsonReporter::testRunStarting( TestRunInfo const& testInfo ) {
|
||||
StreamingReporterBase::testRunStarting( testInfo );
|
||||
void JsonReporter::testRunStarting( TestRunInfo const& runInfo ) {
|
||||
StreamingReporterBase::testRunStarting( runInfo );
|
||||
endListing();
|
||||
|
||||
assert( isInside( Writer::Object ) );
|
||||
|
@@ -74,7 +74,7 @@ namespace Catch {
|
||||
|
||||
static void normalizeNamespaceMarkers(std::string& str) {
|
||||
std::size_t pos = str.find( "::" );
|
||||
while ( pos != str.npos ) {
|
||||
while ( pos != std::string::npos ) {
|
||||
str.replace( pos, 2, "." );
|
||||
pos += 1;
|
||||
pos = str.find( "::", pos );
|
||||
|
@@ -53,7 +53,7 @@ namespace Catch {
|
||||
|
||||
void assertionEnded( AssertionStats const& assertionStats ) override;
|
||||
void sectionEnded( SectionStats const& sectionStats ) override;
|
||||
void testCasePartialEnded(TestCaseStats const& testInfo, uint64_t partNumber) override;
|
||||
void testCasePartialEnded(TestCaseStats const& testStats, uint64_t partNumber) override;
|
||||
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
|
||||
void testRunEnded( TestRunStats const& testRunStats ) override;
|
||||
|
||||
|
@@ -37,7 +37,7 @@ namespace Catch {
|
||||
xml.endElement();
|
||||
}
|
||||
|
||||
void writeRun( TestRunNode const& groupNode );
|
||||
void writeRun( TestRunNode const& runNode );
|
||||
|
||||
void writeTestFile(StringRef filename, std::vector<TestCaseNode const*> const& testCaseNodes);
|
||||
|
||||
|
@@ -35,8 +35,8 @@ namespace Catch {
|
||||
return "Reports test results as TeamCity service messages"s;
|
||||
}
|
||||
|
||||
void testRunStarting( TestRunInfo const& groupInfo ) override;
|
||||
void testRunEnded( TestRunStats const& testGroupStats ) override;
|
||||
void testRunStarting( TestRunInfo const& runInfo ) override;
|
||||
void testRunEnded( TestRunStats const& runStats ) override;
|
||||
|
||||
|
||||
void assertionEnded(AssertionStats const& assertionStats) override;
|
||||
|
@@ -34,7 +34,7 @@ public:
|
||||
return "Custom reporter for testing cumulative reporter base";
|
||||
}
|
||||
|
||||
virtual void testRunEndedCumulative() override;
|
||||
void testRunEndedCumulative() override;
|
||||
};
|
||||
|
||||
CATCH_REGISTER_REPORTER("testReporter", CumulativeBenchmarkReporter)
|
||||
|
@@ -36,6 +36,7 @@ public:
|
||||
|
||||
void testRunStarting( Catch::TestRunInfo const& ) override {
|
||||
std::vector<std::pair<std::string, std::string>> options;
|
||||
options.reserve( m_customOptions.size() );
|
||||
for ( auto const& kv : m_customOptions ) {
|
||||
options.push_back( kv );
|
||||
}
|
||||
|
@@ -16,10 +16,10 @@
|
||||
TEST_CASE("Just a dummy test") {
|
||||
auto i = GENERATE(1, 2, 3);
|
||||
SECTION("a") {
|
||||
REQUIRE(1 != 4);
|
||||
REQUIRE(i != 4);
|
||||
}
|
||||
SECTION("b") {
|
||||
CHECK(1 != 5);
|
||||
CHECK(i != 5);
|
||||
}
|
||||
REQUIRE_THAT(1,
|
||||
Catch::Matchers::Predicate<int>([](int i) {
|
||||
|
@@ -350,20 +350,16 @@ Details.tests.cpp:<line number>: passed: lt( "a", "b" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "a", "B" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "A", "b" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "A", "B" ) for: true
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: tab == '\t' for: '\t' == '\t'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: newline == '\n' for: '\n' == '\n'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: carr_return == '\r' for: '\r' == '\r'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: form_feed == '\f' for: '\f' == '\f'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: space == ' ' for: ' ' == ' '
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'a' == 'a'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'z' == 'z'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'A' == 'A'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'Z' == 'Z'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: null_terminator == '\0' for: 0 == 0
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 2 == 2
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 3 == 3
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 5 == 5
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\t') == "'\\t'" for: "'\t'" == "'\t'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\n') == "'\\n'" for: "'\n'" == "'\n'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\r') == "'\\r'" for: "'\r'" == "'\r'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\f') == "'\\f'" for: "'\f'" == "'\f'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( ' ' ) == "' '" for: "' '" == "' '"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( 'A' ) == "'A'" for: "'A'" == "'A'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( 'z' ) == "'z'" for: "'z'" == "'z'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( '\0' ) == "0" for: "0" == "0"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" for: "2" == "2"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" for: "5" == "5"
|
||||
Clara.tests.cpp:<line number>: passed: name.empty() for: true
|
||||
Clara.tests.cpp:<line number>: passed: name == "foo" for: "foo" == "foo"
|
||||
Clara.tests.cpp:<line number>: passed: !(parse_result) for: !{?}
|
||||
@@ -1737,13 +1733,13 @@ Tag.tests.cpp:<line number>: passed: testCase.tags, VectorContains( Tag( "tag wi
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: std::is_default_constructible<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_default_constructible<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_trivially_copyable<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_trivially_copyable<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
|
||||
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
Misc.tests.cpp:<line number>: passed: v.size() == 10 for: 10 == 10
|
||||
@@ -2483,6 +2479,10 @@ StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, lett
|
||||
StringManip.tests.cpp:<line number>: passed: letters == "replaced" for: "replaced" == "replaced"
|
||||
StringManip.tests.cpp:<line number>: passed: !(Catch::replaceInPlace(letters, "x", "z")) for: !false
|
||||
StringManip.tests.cpp:<line number>: passed: letters == letters for: "abcdefcg" == "abcdefcg"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "c", "cc") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: letters == "abccdefccg" for: "abccdefccg" == "abccdefccg"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(s, "--", "-") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: s == "--" for: "--" == "--"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(s, "'", "|'") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t"
|
||||
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "%somestream" )
|
||||
|
@@ -348,20 +348,16 @@ Details.tests.cpp:<line number>: passed: lt( "a", "b" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "a", "B" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "A", "b" ) for: true
|
||||
Details.tests.cpp:<line number>: passed: lt( "A", "B" ) for: true
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: tab == '\t' for: '\t' == '\t'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: newline == '\n' for: '\n' == '\n'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: carr_return == '\r' for: '\r' == '\r'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: form_feed == '\f' for: '\f' == '\f'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: space == ' ' for: ' ' == ' '
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'a' == 'a'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'z' == 'z'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'A' == 'A'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == chars[i] for: 'Z' == 'Z'
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: null_terminator == '\0' for: 0 == 0
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 2 == 2
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 3 == 3
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 4 == 4
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: c == i for: 5 == 5
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\t') == "'\\t'" for: "'\t'" == "'\t'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\n') == "'\\n'" for: "'\n'" == "'\n'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\r') == "'\\r'" for: "'\r'" == "'\r'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify('\f') == "'\\f'" for: "'\f'" == "'\f'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( ' ' ) == "' '" for: "' '" == "' '"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( 'A' ) == "'A'" for: "'A'" == "'A'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( 'z' ) == "'z'" for: "'z'" == "'z'"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( '\0' ) == "0" for: "0" == "0"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" for: "2" == "2"
|
||||
ToStringGeneral.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" for: "5" == "5"
|
||||
Clara.tests.cpp:<line number>: passed: name.empty() for: true
|
||||
Clara.tests.cpp:<line number>: passed: name == "foo" for: "foo" == "foo"
|
||||
Clara.tests.cpp:<line number>: passed: !(parse_result) for: !{?}
|
||||
@@ -1730,13 +1726,13 @@ Tag.tests.cpp:<line number>: passed: testCase.tags, VectorContains( Tag( "tag wi
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
Class.tests.cpp:<line number>: passed: Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 1 > 0
|
||||
Misc.tests.cpp:<line number>: passed: sizeof(TestType) > 0 for: 4 > 0
|
||||
Misc.tests.cpp:<line number>: passed: std::is_default_constructible<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_default_constructible<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_trivially_copyable<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_trivially_copyable<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: std::is_arithmetic<TestType>::value for: true
|
||||
Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
|
||||
Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
|
||||
Misc.tests.cpp:<line number>: passed: v.size() == 10 for: 10 == 10
|
||||
@@ -2472,6 +2468,10 @@ StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, lett
|
||||
StringManip.tests.cpp:<line number>: passed: letters == "replaced" for: "replaced" == "replaced"
|
||||
StringManip.tests.cpp:<line number>: passed: !(Catch::replaceInPlace(letters, "x", "z")) for: !false
|
||||
StringManip.tests.cpp:<line number>: passed: letters == letters for: "abcdefcg" == "abcdefcg"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(letters, "c", "cc") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: letters == "abccdefccg" for: "abccdefccg" == "abccdefccg"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(s, "--", "-") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: s == "--" for: "--" == "--"
|
||||
StringManip.tests.cpp:<line number>: passed: Catch::replaceInPlace(s, "'", "|'") for: true
|
||||
StringManip.tests.cpp:<line number>: passed: s == "didn|'t" for: "didn|'t" == "didn|'t"
|
||||
Stream.tests.cpp:<line number>: passed: Catch::makeStream( "%somestream" )
|
||||
|
@@ -2904,24 +2904,24 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( tab == '\t' )
|
||||
CHECK( ::Catch::Detail::stringify('\t') == "'\\t'" )
|
||||
with expansion:
|
||||
'\t' == '\t'
|
||||
"'\t'" == "'\t'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( newline == '\n' )
|
||||
CHECK( ::Catch::Detail::stringify('\n') == "'\\n'" )
|
||||
with expansion:
|
||||
'\n' == '\n'
|
||||
"'\n'" == "'\n'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( carr_return == '\r' )
|
||||
CHECK( ::Catch::Detail::stringify('\r') == "'\\r'" )
|
||||
with expansion:
|
||||
'\r' == '\r'
|
||||
"'\r'" == "'\r'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( form_feed == '\f' )
|
||||
CHECK( ::Catch::Detail::stringify('\f') == "'\\f'" )
|
||||
with expansion:
|
||||
'\f' == '\f'
|
||||
"'\f'" == "'\f'"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
@@ -2931,29 +2931,19 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( space == ' ' )
|
||||
CHECK( ::Catch::Detail::stringify( ' ' ) == "' '" )
|
||||
with expansion:
|
||||
' ' == ' '
|
||||
"' '" == "' '"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
CHECK( ::Catch::Detail::stringify( 'A' ) == "'A'" )
|
||||
with expansion:
|
||||
'a' == 'a'
|
||||
"'A'" == "'A'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
CHECK( ::Catch::Detail::stringify( 'z' ) == "'z'" )
|
||||
with expansion:
|
||||
'z' == 'z'
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'A' == 'A'
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'Z' == 'Z'
|
||||
"'z'" == "'z'"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
@@ -2963,29 +2953,19 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( null_terminator == '\0' )
|
||||
CHECK( ::Catch::Detail::stringify( '\0' ) == "0" )
|
||||
with expansion:
|
||||
0 == 0
|
||||
"0" == "0"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
CHECK( ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" )
|
||||
with expansion:
|
||||
2 == 2
|
||||
"2" == "2"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
CHECK( ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
4 == 4
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
5 == 5
|
||||
"5" == "5"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Clara::Arg supports single-arg parse the way Opt does
|
||||
@@ -11675,9 +11655,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_default_constructible<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-copyable and non-
|
||||
@@ -11687,9 +11667,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_default_constructible<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-default-constructible
|
||||
@@ -11699,9 +11679,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_trivially_copyable<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-default-constructible
|
||||
@@ -11711,9 +11691,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_trivially_copyable<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 0
|
||||
@@ -11722,9 +11702,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 1
|
||||
@@ -11733,9 +11713,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 2
|
||||
@@ -11744,9 +11724,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
TemplateTest: vectors can be sized and resized - float
|
||||
@@ -17309,6 +17289,42 @@ StringManip.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
"abcdefcg" == "abcdefcg"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
no replace in already-replaced string
|
||||
lengthening
|
||||
-------------------------------------------------------------------------------
|
||||
StringManip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( Catch::replaceInPlace(letters, "c", "cc") )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( letters == "abccdefccg" )
|
||||
with expansion:
|
||||
"abccdefccg" == "abccdefccg"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
no replace in already-replaced string
|
||||
shortening
|
||||
-------------------------------------------------------------------------------
|
||||
StringManip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( Catch::replaceInPlace(s, "--", "-") )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( s == "--" )
|
||||
with expansion:
|
||||
"--" == "--"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
escape '
|
||||
|
@@ -2902,24 +2902,24 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( tab == '\t' )
|
||||
CHECK( ::Catch::Detail::stringify('\t') == "'\\t'" )
|
||||
with expansion:
|
||||
'\t' == '\t'
|
||||
"'\t'" == "'\t'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( newline == '\n' )
|
||||
CHECK( ::Catch::Detail::stringify('\n') == "'\\n'" )
|
||||
with expansion:
|
||||
'\n' == '\n'
|
||||
"'\n'" == "'\n'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( carr_return == '\r' )
|
||||
CHECK( ::Catch::Detail::stringify('\r') == "'\\r'" )
|
||||
with expansion:
|
||||
'\r' == '\r'
|
||||
"'\r'" == "'\r'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( form_feed == '\f' )
|
||||
CHECK( ::Catch::Detail::stringify('\f') == "'\\f'" )
|
||||
with expansion:
|
||||
'\f' == '\f'
|
||||
"'\f'" == "'\f'"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
@@ -2929,29 +2929,19 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( space == ' ' )
|
||||
CHECK( ::Catch::Detail::stringify( ' ' ) == "' '" )
|
||||
with expansion:
|
||||
' ' == ' '
|
||||
"' '" == "' '"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
CHECK( ::Catch::Detail::stringify( 'A' ) == "'A'" )
|
||||
with expansion:
|
||||
'a' == 'a'
|
||||
"'A'" == "'A'"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
CHECK( ::Catch::Detail::stringify( 'z' ) == "'z'" )
|
||||
with expansion:
|
||||
'z' == 'z'
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'A' == 'A'
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == chars[i] )
|
||||
with expansion:
|
||||
'Z' == 'Z'
|
||||
"'z'" == "'z'"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Character pretty printing
|
||||
@@ -2961,29 +2951,19 @@ ToStringGeneral.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
CHECK( null_terminator == '\0' )
|
||||
CHECK( ::Catch::Detail::stringify( '\0' ) == "0" )
|
||||
with expansion:
|
||||
0 == 0
|
||||
"0" == "0"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
CHECK( ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" )
|
||||
with expansion:
|
||||
2 == 2
|
||||
"2" == "2"
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
CHECK( ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" )
|
||||
with expansion:
|
||||
3 == 3
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
4 == 4
|
||||
|
||||
ToStringGeneral.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( c == i )
|
||||
with expansion:
|
||||
5 == 5
|
||||
"5" == "5"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Clara::Arg supports single-arg parse the way Opt does
|
||||
@@ -11668,9 +11648,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_default_constructible<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-copyable and non-
|
||||
@@ -11680,9 +11660,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_default_constructible<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-default-constructible
|
||||
@@ -11692,9 +11672,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_trivially_copyable<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside non-default-constructible
|
||||
@@ -11704,9 +11684,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_trivially_copyable<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 0
|
||||
@@ -11715,9 +11695,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 1
|
||||
@@ -11726,9 +11706,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
1 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Template test case with test types specified inside std::tuple - MyTypes - 2
|
||||
@@ -11737,9 +11717,9 @@ Misc.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
Misc.tests.cpp:<line number>: PASSED:
|
||||
REQUIRE( sizeof(TestType) > 0 )
|
||||
REQUIRE( std::is_arithmetic<TestType>::value )
|
||||
with expansion:
|
||||
4 > 0
|
||||
true
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
TemplateTest: vectors can be sized and resized - float
|
||||
@@ -17298,6 +17278,42 @@ StringManip.tests.cpp:<line number>: PASSED:
|
||||
with expansion:
|
||||
"abcdefcg" == "abcdefcg"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
no replace in already-replaced string
|
||||
lengthening
|
||||
-------------------------------------------------------------------------------
|
||||
StringManip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( Catch::replaceInPlace(letters, "c", "cc") )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( letters == "abccdefccg" )
|
||||
with expansion:
|
||||
"abccdefccg" == "abccdefccg"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
no replace in already-replaced string
|
||||
shortening
|
||||
-------------------------------------------------------------------------------
|
||||
StringManip.tests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( Catch::replaceInPlace(s, "--", "-") )
|
||||
with expansion:
|
||||
true
|
||||
|
||||
StringManip.tests.cpp:<line number>: PASSED:
|
||||
CHECK( s == "--" )
|
||||
with expansion:
|
||||
"--" == "--"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
replaceInPlace
|
||||
escape '
|
||||
|
@@ -1966,6 +1966,8 @@ at Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace last char" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace all chars" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace no chars" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/no replace in already-replaced string/lengthening" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/no replace in already-replaced string/shortening" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/escape '" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="request an unknown %-starting stream fails" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="resolution" time="{duration}" status="run"/>
|
||||
|
@@ -1965,6 +1965,8 @@ at Message.tests.cpp:<line number>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace last char" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace all chars" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/replace no chars" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/no replace in already-replaced string/lengthening" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/no replace in already-replaced string/shortening" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="replaceInPlace/escape '" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="request an unknown %-starting stream fails" time="{duration}" status="run"/>
|
||||
<testcase classname="<exe-name>.global" name="resolution" time="{duration}" status="run"/>
|
||||
|
@@ -262,6 +262,8 @@ at AssertionHandler.tests.cpp:<line number>
|
||||
<testCase name="replaceInPlace/replace last char" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/replace all chars" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/replace no chars" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/no replace in already-replaced string/lengthening" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/no replace in already-replaced string/shortening" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/escape '" duration="{duration}"/>
|
||||
<testCase name="splitString" duration="{duration}"/>
|
||||
<testCase name="startsWith" duration="{duration}"/>
|
||||
|
@@ -261,6 +261,8 @@ at AssertionHandler.tests.cpp:<line number>
|
||||
<testCase name="replaceInPlace/replace last char" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/replace all chars" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/replace no chars" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/no replace in already-replaced string/lengthening" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/no replace in already-replaced string/shortening" duration="{duration}"/>
|
||||
<testCase name="replaceInPlace/escape '" duration="{duration}"/>
|
||||
<testCase name="splitString" duration="{duration}"/>
|
||||
<testCase name="startsWith" duration="{duration}"/>
|
||||
|
@@ -697,33 +697,25 @@ ok {test-number} - lt( "A", "b" ) for: true
|
||||
# CaseInsensitiveLess is case insensitive
|
||||
ok {test-number} - lt( "A", "B" ) for: true
|
||||
# Character pretty printing
|
||||
ok {test-number} - tab == '\t' for: '\t' == '\t'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\t') == "'\\t'" for: "'\t'" == "'\t'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - newline == '\n' for: '\n' == '\n'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\n') == "'\\n'" for: "'\n'" == "'\n'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - carr_return == '\r' for: '\r' == '\r'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\r') == "'\\r'" for: "'\r'" == "'\r'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - form_feed == '\f' for: '\f' == '\f'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\f') == "'\\f'" for: "'\f'" == "'\f'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - space == ' ' for: ' ' == ' '
|
||||
ok {test-number} - ::Catch::Detail::stringify( ' ' ) == "' '" for: "' '" == "' '"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'a' == 'a'
|
||||
ok {test-number} - ::Catch::Detail::stringify( 'A' ) == "'A'" for: "'A'" == "'A'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'z' == 'z'
|
||||
ok {test-number} - ::Catch::Detail::stringify( 'z' ) == "'z'" for: "'z'" == "'z'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'A' == 'A'
|
||||
ok {test-number} - ::Catch::Detail::stringify( '\0' ) == "0" for: "0" == "0"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'Z' == 'Z'
|
||||
ok {test-number} - ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" for: "2" == "2"
|
||||
# Character pretty printing
|
||||
ok {test-number} - null_terminator == '\0' for: 0 == 0
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 2 == 2
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 3 == 3
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 4 == 4
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 5 == 5
|
||||
ok {test-number} - ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" for: "5" == "5"
|
||||
# Clara::Arg supports single-arg parse the way Opt does
|
||||
ok {test-number} - name.empty() for: true
|
||||
# Clara::Arg supports single-arg parse the way Opt does
|
||||
@@ -2812,19 +2804,19 @@ ok {test-number} - Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
# Template test case method with test types specified inside std::tuple - MyTypes - 2
|
||||
ok {test-number} - Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
|
||||
# Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_default_constructible<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_default_constructible<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_trivially_copyable<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_trivially_copyable<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 2
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# TemplateTest: vectors can be sized and resized - float
|
||||
ok {test-number} - v.size() == 5 for: 5 == 5
|
||||
# TemplateTest: vectors can be sized and resized - float
|
||||
@@ -4206,6 +4198,14 @@ ok {test-number} - !(Catch::replaceInPlace(letters, "x", "z")) for: !false
|
||||
# replaceInPlace
|
||||
ok {test-number} - letters == letters for: "abcdefcg" == "abcdefcg"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(letters, "c", "cc") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - letters == "abccdefccg" for: "abccdefccg" == "abccdefccg"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(s, "--", "-") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - s == "--" for: "--" == "--"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(s, "'", "|'") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - s == "didn|'t" for: "didn|'t" == "didn|'t"
|
||||
|
@@ -695,33 +695,25 @@ ok {test-number} - lt( "A", "b" ) for: true
|
||||
# CaseInsensitiveLess is case insensitive
|
||||
ok {test-number} - lt( "A", "B" ) for: true
|
||||
# Character pretty printing
|
||||
ok {test-number} - tab == '\t' for: '\t' == '\t'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\t') == "'\\t'" for: "'\t'" == "'\t'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - newline == '\n' for: '\n' == '\n'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\n') == "'\\n'" for: "'\n'" == "'\n'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - carr_return == '\r' for: '\r' == '\r'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\r') == "'\\r'" for: "'\r'" == "'\r'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - form_feed == '\f' for: '\f' == '\f'
|
||||
ok {test-number} - ::Catch::Detail::stringify('\f') == "'\\f'" for: "'\f'" == "'\f'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - space == ' ' for: ' ' == ' '
|
||||
ok {test-number} - ::Catch::Detail::stringify( ' ' ) == "' '" for: "' '" == "' '"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'a' == 'a'
|
||||
ok {test-number} - ::Catch::Detail::stringify( 'A' ) == "'A'" for: "'A'" == "'A'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'z' == 'z'
|
||||
ok {test-number} - ::Catch::Detail::stringify( 'z' ) == "'z'" for: "'z'" == "'z'"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'A' == 'A'
|
||||
ok {test-number} - ::Catch::Detail::stringify( '\0' ) == "0" for: "0" == "0"
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == chars[i] for: 'Z' == 'Z'
|
||||
ok {test-number} - ::Catch::Detail::stringify( static_cast<char>(2) ) == "2" for: "2" == "2"
|
||||
# Character pretty printing
|
||||
ok {test-number} - null_terminator == '\0' for: 0 == 0
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 2 == 2
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 3 == 3
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 4 == 4
|
||||
# Character pretty printing
|
||||
ok {test-number} - c == i for: 5 == 5
|
||||
ok {test-number} - ::Catch::Detail::stringify( static_cast<char>(5) ) == "5" for: "5" == "5"
|
||||
# Clara::Arg supports single-arg parse the way Opt does
|
||||
ok {test-number} - name.empty() for: true
|
||||
# Clara::Arg supports single-arg parse the way Opt does
|
||||
@@ -2805,19 +2797,19 @@ ok {test-number} - Template_Fixture<TestType>::m_a == 1 for: 1 == 1
|
||||
# Template test case method with test types specified inside std::tuple - MyTypes - 2
|
||||
ok {test-number} - Template_Fixture<TestType>::m_a == 1 for: 1.0 == 1
|
||||
# Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_default_constructible<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_default_constructible<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_trivially_copyable<TestType>::value for: true
|
||||
# Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_trivially_copyable<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 0
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 1
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 1 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# Template test case with test types specified inside std::tuple - MyTypes - 2
|
||||
ok {test-number} - sizeof(TestType) > 0 for: 4 > 0
|
||||
ok {test-number} - std::is_arithmetic<TestType>::value for: true
|
||||
# TemplateTest: vectors can be sized and resized - float
|
||||
ok {test-number} - v.size() == 5 for: 5 == 5
|
||||
# TemplateTest: vectors can be sized and resized - float
|
||||
@@ -4195,6 +4187,14 @@ ok {test-number} - !(Catch::replaceInPlace(letters, "x", "z")) for: !false
|
||||
# replaceInPlace
|
||||
ok {test-number} - letters == letters for: "abcdefcg" == "abcdefcg"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(letters, "c", "cc") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - letters == "abccdefccg" for: "abccdefccg" == "abccdefccg"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(s, "--", "-") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - s == "--" for: "--" == "--"
|
||||
# replaceInPlace
|
||||
ok {test-number} - Catch::replaceInPlace(s, "'", "|'") for: true
|
||||
# replaceInPlace
|
||||
ok {test-number} - s == "didn|'t" for: "didn|'t" == "didn|'t"
|
||||
|
@@ -3142,34 +3142,34 @@ Nor would this
|
||||
<Section name="Specifically escaped" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
tab == '\t'
|
||||
::Catch::Detail::stringify('\t') == "'\\t'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\t' == '\t'
|
||||
"'\t'" == "'\t'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
newline == '\n'
|
||||
::Catch::Detail::stringify('\n') == "'\\n'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\n' == '\n'
|
||||
"'\n'" == "'\n'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
carr_return == '\r'
|
||||
::Catch::Detail::stringify('\r') == "'\\r'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\r' == '\r'
|
||||
"'\r'" == "'\r'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
form_feed == '\f'
|
||||
::Catch::Detail::stringify('\f') == "'\\f'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\f' == '\f'
|
||||
"'\f'" == "'\f'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="4" failures="0" expectedFailures="0" skipped="false"/>
|
||||
@@ -3177,88 +3177,56 @@ Nor would this
|
||||
<Section name="General chars" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
space == ' '
|
||||
::Catch::Detail::stringify( ' ' ) == "' '"
|
||||
</Original>
|
||||
<Expanded>
|
||||
' ' == ' '
|
||||
"' '" == "' '"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
::Catch::Detail::stringify( 'A' ) == "'A'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'a' == 'a'
|
||||
"'A'" == "'A'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
::Catch::Detail::stringify( 'z' ) == "'z'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'z' == 'z'
|
||||
"'z'" == "'z'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
</Original>
|
||||
<Expanded>
|
||||
'A' == 'A'
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
</Original>
|
||||
<Expanded>
|
||||
'Z' == 'Z'
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="5" failures="0" expectedFailures="0" skipped="false"/>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="Low ASCII" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
null_terminator == '\0'
|
||||
::Catch::Detail::stringify( '\0' ) == "0"
|
||||
</Original>
|
||||
<Expanded>
|
||||
0 == 0
|
||||
"0" == "0"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
::Catch::Detail::stringify( static_cast<char>(2) ) == "2"
|
||||
</Original>
|
||||
<Expanded>
|
||||
2 == 2
|
||||
"2" == "2"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
::Catch::Detail::stringify( static_cast<char>(5) ) == "5"
|
||||
</Original>
|
||||
<Expanded>
|
||||
3 == 3
|
||||
"5" == "5"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 == 4
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
</Original>
|
||||
<Expanded>
|
||||
5 == 5
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="5" failures="0" expectedFailures="0" skipped="false"/>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
@@ -13592,10 +13560,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_default_constructible<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13603,10 +13571,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_default_constructible<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13614,10 +13582,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_trivially_copyable<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13625,10 +13593,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_trivially_copyable<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13636,10 +13604,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13647,10 +13615,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13658,10 +13626,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 2" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -20066,6 +20034,50 @@ b1!
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="no replace in already-replaced string" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Section name="lengthening" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
Catch::replaceInPlace(letters, "c", "cc")
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
letters == "abccdefccg"
|
||||
</Original>
|
||||
<Expanded>
|
||||
"abccdefccg" == "abccdefccg"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="no replace in already-replaced string" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Section name="shortening" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
Catch::replaceInPlace(s, "--", "-")
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
s == "--"
|
||||
</Original>
|
||||
<Expanded>
|
||||
"--" == "--"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="escape '" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
|
@@ -3142,34 +3142,34 @@ Nor would this
|
||||
<Section name="Specifically escaped" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
tab == '\t'
|
||||
::Catch::Detail::stringify('\t') == "'\\t'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\t' == '\t'
|
||||
"'\t'" == "'\t'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
newline == '\n'
|
||||
::Catch::Detail::stringify('\n') == "'\\n'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\n' == '\n'
|
||||
"'\n'" == "'\n'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
carr_return == '\r'
|
||||
::Catch::Detail::stringify('\r') == "'\\r'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\r' == '\r'
|
||||
"'\r'" == "'\r'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
form_feed == '\f'
|
||||
::Catch::Detail::stringify('\f') == "'\\f'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'\f' == '\f'
|
||||
"'\f'" == "'\f'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="4" failures="0" expectedFailures="0" skipped="false"/>
|
||||
@@ -3177,88 +3177,56 @@ Nor would this
|
||||
<Section name="General chars" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
space == ' '
|
||||
::Catch::Detail::stringify( ' ' ) == "' '"
|
||||
</Original>
|
||||
<Expanded>
|
||||
' ' == ' '
|
||||
"' '" == "' '"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
::Catch::Detail::stringify( 'A' ) == "'A'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'a' == 'a'
|
||||
"'A'" == "'A'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
::Catch::Detail::stringify( 'z' ) == "'z'"
|
||||
</Original>
|
||||
<Expanded>
|
||||
'z' == 'z'
|
||||
"'z'" == "'z'"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
</Original>
|
||||
<Expanded>
|
||||
'A' == 'A'
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == chars[i]
|
||||
</Original>
|
||||
<Expanded>
|
||||
'Z' == 'Z'
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="5" failures="0" expectedFailures="0" skipped="false"/>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="Low ASCII" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
null_terminator == '\0'
|
||||
::Catch::Detail::stringify( '\0' ) == "0"
|
||||
</Original>
|
||||
<Expanded>
|
||||
0 == 0
|
||||
"0" == "0"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
::Catch::Detail::stringify( static_cast<char>(2) ) == "2"
|
||||
</Original>
|
||||
<Expanded>
|
||||
2 == 2
|
||||
"2" == "2"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
::Catch::Detail::stringify( static_cast<char>(5) ) == "5"
|
||||
</Original>
|
||||
<Expanded>
|
||||
3 == 3
|
||||
"5" == "5"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 == 4
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/ToStringGeneral.tests.cpp" >
|
||||
<Original>
|
||||
c == i
|
||||
</Original>
|
||||
<Expanded>
|
||||
5 == 5
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="5" failures="0" expectedFailures="0" skipped="false"/>
|
||||
<OverallResults successes="3" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
</TestCase>
|
||||
@@ -13592,10 +13560,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_default_constructible<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13603,10 +13571,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_default_constructible<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13614,10 +13582,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_trivially_copyable<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13625,10 +13593,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_trivially_copyable<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13636,10 +13604,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 0" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13647,10 +13615,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 1" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
1 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -13658,10 +13626,10 @@ Message from section two
|
||||
<TestCase name="Template test case with test types specified inside std::tuple - MyTypes - 2" tags="[list][template]" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/UsageTests/Misc.tests.cpp" >
|
||||
<Original>
|
||||
sizeof(TestType) > 0
|
||||
std::is_arithmetic<TestType>::value
|
||||
</Original>
|
||||
<Expanded>
|
||||
4 > 0
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true" skips="0"/>
|
||||
@@ -20065,6 +20033,50 @@ b1!
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="no replace in already-replaced string" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Section name="lengthening" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
Catch::replaceInPlace(letters, "c", "cc")
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
letters == "abccdefccg"
|
||||
</Original>
|
||||
<Expanded>
|
||||
"abccdefccg" == "abccdefccg"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="no replace in already-replaced string" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Section name="shortening" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
Catch::replaceInPlace(s, "--", "-")
|
||||
</Original>
|
||||
<Expanded>
|
||||
true
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
s == "--"
|
||||
</Original>
|
||||
<Expanded>
|
||||
"--" == "--"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<OverallResults successes="2" failures="0" expectedFailures="0" skipped="false"/>
|
||||
</Section>
|
||||
<Section name="escape '" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/StringManip.tests.cpp" >
|
||||
<Original>
|
||||
|
@@ -120,13 +120,13 @@ TEST_CASE( "Optional supports move ops", "[optional][approvals]" ) {
|
||||
}
|
||||
SECTION( "Move construction from optional" ) {
|
||||
Optional<MoveChecker> opt_B( CATCH_MOVE( opt_A ) );
|
||||
REQUIRE( opt_A->has_moved );
|
||||
REQUIRE( opt_A->has_moved ); // NOLINT(clang-analyzer-cplusplus.Move)
|
||||
}
|
||||
SECTION( "Move assignment from optional" ) {
|
||||
Optional<MoveChecker> opt_B( opt_A );
|
||||
REQUIRE_FALSE( opt_A->has_moved );
|
||||
opt_B = CATCH_MOVE( opt_A );
|
||||
REQUIRE( opt_A->has_moved );
|
||||
REQUIRE( opt_A->has_moved ); // NOLINT(clang-analyzer-cplusplus.Move)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#include <catch2/generators/catch_generators_adapters.hpp>
|
||||
#include <catch2/generators/catch_generators_random.hpp>
|
||||
#include <catch2/generators/catch_generators_range.hpp>
|
||||
#include <catch2/generators/catch_generator_exception.hpp>
|
||||
|
||||
// Tests of generator implementation details
|
||||
TEST_CASE("Generators internals", "[generators][internals]") {
|
||||
|
@@ -493,7 +493,6 @@ TEMPLATE_TEST_CASE( "uniform_integer_distribution is reproducible",
|
||||
REQUIRE_THAT(generated, Catch::Matchers::RangeEquals(uniform_integer_test_params<TestType>::expected));
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
struct uniform_fp_test_params;
|
||||
@@ -551,6 +550,20 @@ namespace {
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
// The reproducibility tests assume that operations on `float`/`double`
|
||||
// happen in the same precision as the operated-upon type. This is
|
||||
// generally true, unless the code is compiled for 32 bit targets without
|
||||
// SSE2 enabled, in which case the operations are done in the x87 FPU,
|
||||
// which usually implies doing math in 80 bit floats, and then rounding
|
||||
// into smaller type when the type is saved into memory. This obviously
|
||||
// leads to a different answer, than doing the math in the correct precision.
|
||||
#if ( defined( _MSC_VER ) && _M_IX86_FP < 2 ) || \
|
||||
( defined( __GNUC__ ) && !defined( __SSE2_MATH__ ) )
|
||||
# define CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS
|
||||
#endif
|
||||
|
||||
#if !defined( CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS )
|
||||
|
||||
TEMPLATE_TEST_CASE( "uniform_floating_point_distribution is reproducible",
|
||||
"[rng][distribution][floating-point][approvals]",
|
||||
float,
|
||||
@@ -570,6 +583,8 @@ TEMPLATE_TEST_CASE( "uniform_floating_point_distribution is reproducible",
|
||||
REQUIRE_THAT( generated, Catch::Matchers::RangeEquals( uniform_fp_test_params<TestType>::expected ) );
|
||||
}
|
||||
|
||||
#endif // ^^ float reproducibility tests are enabled
|
||||
|
||||
TEMPLATE_TEST_CASE( "uniform_floating_point_distribution can handle unitary ranges",
|
||||
"[rng][distribution][floating-point][approvals]",
|
||||
float,
|
||||
|
@@ -107,7 +107,7 @@ TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) {
|
||||
for (auto const& factory : factories) {
|
||||
INFO("Tested reporter: " << factory.first);
|
||||
auto sstream = Catch::Detail::make_unique<StringIStream>();
|
||||
auto& sstreamRef = *sstream.get();
|
||||
auto& sstreamRef = *sstream;
|
||||
|
||||
Catch::ConfigData cfg_data;
|
||||
cfg_data.rngSeed = 1234;
|
||||
|
@@ -57,6 +57,17 @@ TEST_CASE("replaceInPlace", "[string-manip]") {
|
||||
CHECK_FALSE(Catch::replaceInPlace(letters, "x", "z"));
|
||||
CHECK(letters == letters);
|
||||
}
|
||||
SECTION("no replace in already-replaced string") {
|
||||
SECTION("lengthening") {
|
||||
CHECK(Catch::replaceInPlace(letters, "c", "cc"));
|
||||
CHECK(letters == "abccdefccg");
|
||||
}
|
||||
SECTION("shortening") {
|
||||
std::string s = "----";
|
||||
CHECK(Catch::replaceInPlace(s, "--", "-"));
|
||||
CHECK(s == "--");
|
||||
}
|
||||
}
|
||||
SECTION("escape '") {
|
||||
std::string s = "didn't";
|
||||
CHECK(Catch::replaceInPlace(s, "'", "|'"));
|
||||
|
@@ -236,7 +236,7 @@ TEST_CASE( "Parse test names and tags", "[command-line][test-spec][approvals]" )
|
||||
CHECK( spec.matches( *tcD ) == false );
|
||||
}
|
||||
SECTION( "two wildcarded names" ) {
|
||||
TestSpec spec = parseTestSpec( "\"longer*\"\"*spaces\"" );
|
||||
TestSpec spec = parseTestSpec( R"("longer*""*spaces")" );
|
||||
CHECK( spec.hasFilters() == true );
|
||||
CHECK( spec.matches( *tcA ) == false );
|
||||
CHECK( spec.matches( *tcB ) == false );
|
||||
|
@@ -152,7 +152,7 @@ TEST_CASE( "TextFlow::Column respects indentation for empty lines",
|
||||
|
||||
std::string written = as_written(col);
|
||||
|
||||
REQUIRE(as_written(col) == " \n \n third line");
|
||||
REQUIRE(written == " \n \n third line");
|
||||
}
|
||||
|
||||
TEST_CASE( "TextFlow::Column leading/trailing whitespace",
|
||||
|
@@ -20,7 +20,6 @@ CATCH_REGISTER_TAG_ALIAS("[@tricky]", "[tricky]~[.]")
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic ignored "-Wpadded"
|
||||
# pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -90,14 +90,14 @@ TEST_CASE("Benchmark containers", "[!benchmark]") {
|
||||
};
|
||||
REQUIRE(v.size() == size);
|
||||
|
||||
int array[size];
|
||||
int array[size] {};
|
||||
BENCHMARK("A fixed size array that should require no allocations") {
|
||||
for (int i = 0; i < size; ++i)
|
||||
array[i] = i;
|
||||
};
|
||||
int sum = 0;
|
||||
for (int i = 0; i < size; ++i)
|
||||
sum += array[i];
|
||||
for (int val : array)
|
||||
sum += val;
|
||||
REQUIRE(sum > size);
|
||||
|
||||
SECTION("XYZ") {
|
||||
@@ -121,8 +121,8 @@ TEST_CASE("Benchmark containers", "[!benchmark]") {
|
||||
runs = benchmarkIndex;
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
REQUIRE(v[i] == runs);
|
||||
for (int val : v) {
|
||||
REQUIRE(val == runs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,8 +135,8 @@ TEST_CASE("Benchmark containers", "[!benchmark]") {
|
||||
for (int i = 0; i < size; ++i)
|
||||
v[i] = generated;
|
||||
};
|
||||
for (size_t i = 0; i < v.size(); ++i) {
|
||||
REQUIRE(v[i] == generated);
|
||||
for (int val : v) {
|
||||
REQUIRE(val == generated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -39,7 +39,7 @@ namespace {
|
||||
};
|
||||
|
||||
template <typename T> struct Template_Fixture_2 {
|
||||
Template_Fixture_2() {}
|
||||
Template_Fixture_2() = default;
|
||||
|
||||
T m_a;
|
||||
};
|
||||
|
@@ -313,11 +313,12 @@ TEST_CASE("ADL universal operators don't hijack expression deconstruction", "[co
|
||||
REQUIRE(0 ^ adl::always_true{});
|
||||
}
|
||||
|
||||
TEST_CASE( "#2555 - types that can only be compared with 0 literal (not int/long) are supported", "[compilation][approvals]" ) {
|
||||
TEST_CASE( "#2555 - types that can only be compared with 0 literal implemented as pointer conversion are supported",
|
||||
"[compilation][approvals]" ) {
|
||||
REQUIRE( TypeWithLit0Comparisons{} < 0 );
|
||||
REQUIRE_FALSE( 0 < TypeWithLit0Comparisons{} );
|
||||
REQUIRE( TypeWithLit0Comparisons{} <= 0 );
|
||||
REQUIRE_FALSE( 0 > TypeWithLit0Comparisons{} );
|
||||
REQUIRE_FALSE( 0 <= TypeWithLit0Comparisons{} );
|
||||
|
||||
REQUIRE( TypeWithLit0Comparisons{} > 0 );
|
||||
REQUIRE_FALSE( 0 > TypeWithLit0Comparisons{} );
|
||||
@@ -330,6 +331,72 @@ TEST_CASE( "#2555 - types that can only be compared with 0 literal (not int/long
|
||||
REQUIRE_FALSE( 0 != TypeWithLit0Comparisons{} );
|
||||
}
|
||||
|
||||
// These tests require `consteval` to propagate through `constexpr` calls
|
||||
// which is a late DR against C++20.
|
||||
#if defined( CATCH_CPP20_OR_GREATER ) && defined( __cpp_consteval ) && \
|
||||
__cpp_consteval >= 202211L
|
||||
// Can't have internal linkage to avoid warnings
|
||||
void ZeroLiteralErrorFunc();
|
||||
namespace {
|
||||
struct ZeroLiteralConsteval {
|
||||
template <class T, std::enable_if_t<std::is_same_v<T, int>, int> = 0>
|
||||
consteval ZeroLiteralConsteval( T zero ) noexcept {
|
||||
if ( zero != 0 ) { ZeroLiteralErrorFunc(); }
|
||||
}
|
||||
};
|
||||
|
||||
// Should only be constructible from literal 0. Uses the propagating
|
||||
// consteval constructor trick (currently used by MSVC, might be used
|
||||
// by libc++ in the future as well).
|
||||
struct TypeWithConstevalLit0Comparison {
|
||||
# define DEFINE_COMP_OP( op ) \
|
||||
constexpr friend bool operator op( TypeWithConstevalLit0Comparison, \
|
||||
ZeroLiteralConsteval ) { \
|
||||
return true; \
|
||||
} \
|
||||
constexpr friend bool operator op( ZeroLiteralConsteval, \
|
||||
TypeWithConstevalLit0Comparison ) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
DEFINE_COMP_OP( < )
|
||||
DEFINE_COMP_OP( <= )
|
||||
DEFINE_COMP_OP( > )
|
||||
DEFINE_COMP_OP( >= )
|
||||
DEFINE_COMP_OP( == )
|
||||
DEFINE_COMP_OP( != )
|
||||
|
||||
#undef DEFINE_COMP_OP
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Catch {
|
||||
template <>
|
||||
struct capture_by_value<TypeWithConstevalLit0Comparison> : std::true_type {};
|
||||
}
|
||||
|
||||
TEST_CASE( "#2555 - types that can only be compared with 0 literal implemented as consteval check are supported",
|
||||
"[compilation][approvals]" ) {
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} < 0 );
|
||||
REQUIRE_FALSE( 0 < TypeWithConstevalLit0Comparison{} );
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} <= 0 );
|
||||
REQUIRE_FALSE( 0 <= TypeWithConstevalLit0Comparison{} );
|
||||
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} > 0 );
|
||||
REQUIRE_FALSE( 0 > TypeWithConstevalLit0Comparison{} );
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} >= 0 );
|
||||
REQUIRE_FALSE( 0 >= TypeWithConstevalLit0Comparison{} );
|
||||
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} == 0 );
|
||||
REQUIRE_FALSE( 0 == TypeWithConstevalLit0Comparison{} );
|
||||
REQUIRE( TypeWithConstevalLit0Comparison{} != 0 );
|
||||
REQUIRE_FALSE( 0 != TypeWithConstevalLit0Comparison{} );
|
||||
}
|
||||
|
||||
#endif // C++20 consteval
|
||||
|
||||
|
||||
namespace {
|
||||
struct MultipleImplicitConstructors {
|
||||
MultipleImplicitConstructors( double ) {}
|
||||
|
@@ -119,7 +119,7 @@ TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect
|
||||
try {
|
||||
throw std::domain_error( "unexpected exception" );
|
||||
}
|
||||
catch(...) {}
|
||||
catch(...) {} // NOLINT(bugprone-empty-catch)
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ TEST_CASE( "Custom exceptions can be translated when testing for throwing as som
|
||||
}
|
||||
|
||||
TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]" ) {
|
||||
throw double( 3.14 );
|
||||
throw double( 3.14 ); // NOLINT(readability-redundant-casting): the type is important here, so we want to be explicit
|
||||
}
|
||||
|
||||
TEST_CASE("Thrown string literals are translated", "[.][failing][!throws]") {
|
||||
|
@@ -1027,7 +1027,6 @@ TEST_CASE( "Combining MatchNotOfGeneric does not nest",
|
||||
}
|
||||
|
||||
struct EvilAddressOfOperatorUsed : std::exception {
|
||||
EvilAddressOfOperatorUsed() {}
|
||||
const char* what() const noexcept override {
|
||||
return "overloaded address-of operator of matcher was used instead of "
|
||||
"std::addressof";
|
||||
@@ -1035,7 +1034,6 @@ struct EvilAddressOfOperatorUsed : std::exception {
|
||||
};
|
||||
|
||||
struct EvilCommaOperatorUsed : std::exception {
|
||||
EvilCommaOperatorUsed() {}
|
||||
const char* what() const noexcept override {
|
||||
return "overloaded comma operator of matcher was used";
|
||||
}
|
||||
@@ -1073,7 +1071,6 @@ struct ImmovableMatcher : Catch::Matchers::MatcherGenericBase {
|
||||
};
|
||||
|
||||
struct MatcherWasMovedOrCopied : std::exception {
|
||||
MatcherWasMovedOrCopied() {}
|
||||
const char* what() const noexcept override {
|
||||
return "attempted to copy or move a matcher";
|
||||
}
|
||||
@@ -1081,17 +1078,20 @@ struct MatcherWasMovedOrCopied : std::exception {
|
||||
|
||||
struct ThrowOnCopyOrMoveMatcher : Catch::Matchers::MatcherGenericBase {
|
||||
ThrowOnCopyOrMoveMatcher() = default;
|
||||
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher const& ):
|
||||
Catch::Matchers::MatcherGenericBase() {
|
||||
|
||||
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher const& other ):
|
||||
Catch::Matchers::MatcherGenericBase( other ) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher&& ):
|
||||
Catch::Matchers::MatcherGenericBase() {
|
||||
// NOLINTNEXTLINE(performance-noexcept-move-constructor)
|
||||
[[noreturn]] ThrowOnCopyOrMoveMatcher( ThrowOnCopyOrMoveMatcher&& other ):
|
||||
Catch::Matchers::MatcherGenericBase( CATCH_MOVE(other) ) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
ThrowOnCopyOrMoveMatcher& operator=( ThrowOnCopyOrMoveMatcher const& ) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
// NOLINTNEXTLINE(performance-noexcept-move-constructor)
|
||||
ThrowOnCopyOrMoveMatcher& operator=( ThrowOnCopyOrMoveMatcher&& ) {
|
||||
throw MatcherWasMovedOrCopied();
|
||||
}
|
||||
|
@@ -80,20 +80,20 @@ TEST_CASE( "Output from all sections is reported", "[failing][messages][.]" ) {
|
||||
|
||||
TEST_CASE( "Standard output from all sections is reported", "[messages][.]" ) {
|
||||
SECTION( "one" ) {
|
||||
std::cout << "Message from section one" << std::endl;
|
||||
std::cout << "Message from section one\n";
|
||||
}
|
||||
|
||||
SECTION( "two" ) {
|
||||
std::cout << "Message from section two" << std::endl;
|
||||
std::cout << "Message from section two\n";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "Standard error is reported and redirected", "[messages][.][approvals]" ) {
|
||||
SECTION( "std::cerr" ) {
|
||||
std::cerr << "Write to std::cerr" << std::endl;
|
||||
std::cerr << "Write to std::cerr\n";
|
||||
}
|
||||
SECTION( "std::clog" ) {
|
||||
std::clog << "Write to std::clog" << std::endl;
|
||||
std::clog << "Write to std::clog\n";
|
||||
}
|
||||
SECTION( "Interleaved writes to cerr and clog" ) {
|
||||
std::cerr << "Inter";
|
||||
@@ -101,7 +101,7 @@ TEST_CASE( "Standard error is reported and redirected", "[messages][.][approvals
|
||||
std::cerr << ' ';
|
||||
std::clog << "writes";
|
||||
std::cerr << " to error";
|
||||
std::clog << " streams" << std::endl;
|
||||
std::clog << " streams\n" << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,11 +11,6 @@
|
||||
#include <catch2/internal/catch_config_wchar.hpp>
|
||||
#include <catch2/internal/catch_windows_h_proxy.hpp>
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
||||
#endif
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cerrno>
|
||||
@@ -158,9 +153,9 @@ TEST_CASE( "looped tests", "[.][failing]" ) {
|
||||
}
|
||||
|
||||
TEST_CASE( "Sends stuff to stdout and stderr", "[.]" ) {
|
||||
std::cout << "A string sent directly to stdout" << std::endl;
|
||||
std::cerr << "A string sent directly to stderr" << std::endl;
|
||||
std::clog << "A string sent to stderr via clog" << std::endl;
|
||||
std::cout << "A string sent directly to stdout\n" << std::flush;
|
||||
std::cerr << "A string sent directly to stderr\n" << std::flush;
|
||||
std::clog << "A string sent to stderr via clog\n" << std::flush;
|
||||
}
|
||||
|
||||
TEST_CASE( "null strings" ) {
|
||||
@@ -396,7 +391,7 @@ TEMPLATE_PRODUCT_TEST_CASE("Product with differing arities", "[template][product
|
||||
using MyTypes = std::tuple<int, char, float>;
|
||||
TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside std::tuple", "[template][list]", MyTypes)
|
||||
{
|
||||
REQUIRE(sizeof(TestType) > 0);
|
||||
REQUIRE(std::is_arithmetic<TestType>::value);
|
||||
}
|
||||
|
||||
struct NonDefaultConstructibleType {
|
||||
@@ -406,7 +401,7 @@ struct NonDefaultConstructibleType {
|
||||
using MyNonDefaultConstructibleTypes = std::tuple<NonDefaultConstructibleType, float>;
|
||||
TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside non-default-constructible std::tuple", "[template][list]", MyNonDefaultConstructibleTypes)
|
||||
{
|
||||
REQUIRE(sizeof(TestType) > 0);
|
||||
REQUIRE(std::is_trivially_copyable<TestType>::value);
|
||||
}
|
||||
|
||||
struct NonCopyableAndNonMovableType {
|
||||
@@ -421,7 +416,7 @@ struct NonCopyableAndNonMovableType {
|
||||
using NonCopyableAndNonMovableTypes = std::tuple<NonCopyableAndNonMovableType, float>;
|
||||
TEMPLATE_LIST_TEST_CASE("Template test case with test types specified inside non-copyable and non-movable std::tuple", "[template][list]", NonCopyableAndNonMovableTypes)
|
||||
{
|
||||
REQUIRE(sizeof(TestType) > 0);
|
||||
REQUIRE(std::is_default_constructible<TestType>::value);
|
||||
}
|
||||
|
||||
// https://github.com/philsquared/Catch/issues/166
|
||||
|
@@ -14,31 +14,20 @@
|
||||
|
||||
TEST_CASE( "Character pretty printing" ){
|
||||
SECTION("Specifically escaped"){
|
||||
char tab = '\t';
|
||||
char newline = '\n';
|
||||
char carr_return = '\r';
|
||||
char form_feed = '\f';
|
||||
CHECK(tab == '\t');
|
||||
CHECK(newline == '\n');
|
||||
CHECK(carr_return == '\r');
|
||||
CHECK(form_feed == '\f');
|
||||
CHECK(::Catch::Detail::stringify('\t') == "'\\t'");
|
||||
CHECK(::Catch::Detail::stringify('\n') == "'\\n'");
|
||||
CHECK(::Catch::Detail::stringify('\r') == "'\\r'");
|
||||
CHECK(::Catch::Detail::stringify('\f') == "'\\f'");
|
||||
}
|
||||
SECTION("General chars"){
|
||||
char space = ' ';
|
||||
CHECK(space == ' ');
|
||||
char chars[] = {'a', 'z', 'A', 'Z'};
|
||||
for (int i = 0; i < 4; ++i){
|
||||
char c = chars[i];
|
||||
REQUIRE(c == chars[i]);
|
||||
}
|
||||
CHECK(::Catch::Detail::stringify( ' ' ) == "' '" );
|
||||
CHECK(::Catch::Detail::stringify( 'A' ) == "'A'" );
|
||||
CHECK(::Catch::Detail::stringify( 'z' ) == "'z'" );
|
||||
}
|
||||
SECTION("Low ASCII"){
|
||||
char null_terminator = '\0';
|
||||
CHECK(null_terminator == '\0');
|
||||
for (int i = 2; i < 6; ++i){
|
||||
char c = static_cast<char>(i);
|
||||
REQUIRE(c == i);
|
||||
}
|
||||
CHECK(::Catch::Detail::stringify( '\0' ) == "0" );
|
||||
CHECK(::Catch::Detail::stringify( static_cast<char>(2) ) == "2" );
|
||||
CHECK(::Catch::Detail::stringify( static_cast<char>(5) ) == "5" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -261,7 +261,7 @@ TEST_CASE( "non streamable - with conv. op", "[Tricky]" )
|
||||
|
||||
inline void foo() {}
|
||||
|
||||
typedef void (*fooptr_t)();
|
||||
using fooptr_t = void (*)();
|
||||
|
||||
TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" )
|
||||
{
|
||||
@@ -281,7 +281,7 @@ struct S
|
||||
|
||||
TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer][approvals]" )
|
||||
{
|
||||
typedef void (S::*MF)();
|
||||
using MF = void (S::*)();
|
||||
MF m = &S::f;
|
||||
|
||||
CHECK( m == &S::f );
|
||||
|
@@ -12,22 +12,27 @@
|
||||
#include <type_traits>
|
||||
|
||||
// Should only be constructible from literal 0.
|
||||
// Based on the constructor from pointer trick, used by libstdc++ and libc++
|
||||
// (formerly also MSVC, but they've moved to consteval int constructor).
|
||||
// Used by `TypeWithLit0Comparisons` for testing comparison
|
||||
// ops that only work with literal zero, the way std::*orderings do
|
||||
struct ZeroLiteralDetector {
|
||||
constexpr ZeroLiteralDetector( ZeroLiteralDetector* ) noexcept {}
|
||||
struct ZeroLiteralAsPointer {
|
||||
constexpr ZeroLiteralAsPointer( ZeroLiteralAsPointer* ) noexcept {}
|
||||
|
||||
template <typename T,
|
||||
typename = std::enable_if_t<!std::is_same<T, int>::value>>
|
||||
constexpr ZeroLiteralDetector( T ) = delete;
|
||||
constexpr ZeroLiteralAsPointer( T ) = delete;
|
||||
};
|
||||
|
||||
|
||||
struct TypeWithLit0Comparisons {
|
||||
#define DEFINE_COMP_OP( op ) \
|
||||
friend bool operator op( TypeWithLit0Comparisons, ZeroLiteralDetector ) { \
|
||||
constexpr friend bool operator op( TypeWithLit0Comparisons, \
|
||||
ZeroLiteralAsPointer ) { \
|
||||
return true; \
|
||||
} \
|
||||
friend bool operator op( ZeroLiteralDetector, TypeWithLit0Comparisons ) { \
|
||||
constexpr friend bool operator op( ZeroLiteralAsPointer, \
|
||||
TypeWithLit0Comparisons ) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
|
@@ -89,7 +89,7 @@ def updateCmakeFile(version):
|
||||
def updateMesonFile(version):
|
||||
with open(mesonPath, 'rb') as file:
|
||||
lines = file.readlines()
|
||||
replacementRegex = re.compile(b'''version\s*:\s*'(\\d+.\\d+.\\d+)', # CML version placeholder, don't delete''')
|
||||
replacementRegex = re.compile(b'''version\\s*:\\s*'(\\d+.\\d+.\\d+)', # CML version placeholder, don't delete''')
|
||||
replacement = '''version: '{0}', # CML version placeholder, don't delete'''.format(version.getVersionString()).encode('ascii')
|
||||
with open(mesonPath, 'wb') as file:
|
||||
for line in lines:
|
||||
|
Reference in New Issue
Block a user