diff --git a/.gitmodules b/.gitmodules index 53dd13c..1190757 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,11 +3,6 @@ url = https://github.com/rmontanana/mdlp main = main update = merge -[submodule "tests/lib/catch2"] - path = tests/lib/catch2 - main = v2.x - update = merge - url = https://github.com/catchorg/Catch2.git [submodule "lib/json"] path = lib/json url = https://github.com/nlohmann/json.git diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a18c9..54eb454 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactor library ArffFile to limit the number of samples with a parameter. - Refactor tests libraries location to test/lib - Refactor loadDataset function in tests. +- Remove conditionalEdgeWeights method in BayesMetrics. ## [1.0.5] 2024-04-20 @@ -39,6 +40,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The worse model count in BoostAODE is reset to 0 every time a new model produces better accuracy, so the tolerance of the model is meant to be the number of **consecutive** models that produce worse accuracy. - Default hyperparameter values in BoostAODE: bisection is true, maxTolerance is 3, convergence is true +### Removed + +- The 'predict_single' hyperparameter from the BoostAODE class. +- The 'repeatSparent' hyperparameter from the BoostAODE class. + ## [1.0.4] 2024-03-06 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ab746e..69981dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,7 @@ add_subdirectory(bayesnet) # ------- if (ENABLE_TESTING) MESSAGE("Testing enabled") - add_git_submodule("tests/lib/catch2") + add_subdirectory("tests/lib/catch2") add_subdirectory(tests/lib/Files) include(CTest) add_subdirectory(tests) diff --git a/README.md b/README.md index b290e50..45e84cd 100644 --- a/README.md +++ b/README.md @@ -75,4 +75,4 @@ make sample fname=tests/data/glass.arff ## Coverage report -[Coverage report](html/index.html) +### [Coverage report](docs/coverage.pdf) diff --git a/bayesnet/ensembles/BoostAODE.h b/bayesnet/ensembles/BoostAODE.h index 2e2851b..dac0004 100644 --- a/bayesnet/ensembles/BoostAODE.h +++ b/bayesnet/ensembles/BoostAODE.h @@ -11,19 +11,19 @@ #include "bayesnet/feature_selection/FeatureSelect.h" #include "Ensemble.h" namespace bayesnet { - struct { + const struct { std::string CFS = "CFS"; std::string FCBF = "FCBF"; std::string IWSS = "IWSS"; }SelectFeatures; - struct { + const struct { std::string ASC = "asc"; std::string DESC = "desc"; std::string RAND = "rand"; }Orders; class BoostAODE : public Ensemble { public: - BoostAODE(bool predict_voting = false); + explicit BoostAODE(bool predict_voting = false); virtual ~BoostAODE() = default; std::vector graph(const std::string& title = "BoostAODE") const override; void setHyperparameters(const nlohmann::json& hyperparameters_) override; diff --git a/bayesnet/utils/BayesMetrics.cc b/bayesnet/utils/BayesMetrics.cc index 5e041a7..07de7cb 100644 --- a/bayesnet/utils/BayesMetrics.cc +++ b/bayesnet/utils/BayesMetrics.cc @@ -10,17 +10,17 @@ namespace bayesnet { //samples is n+1xm tensor used to fit the model Metrics::Metrics(const torch::Tensor& samples, const std::vector& features, const std::string& className, const int classNumStates) : samples(samples) - , features(features) , className(className) + , features(features) , classNumStates(classNumStates) { } //samples is n+1xm std::vector used to fit the model Metrics::Metrics(const std::vector>& vsamples, const std::vector& labels, const std::vector& features, const std::string& className, const int classNumStates) - : features(features) + : samples(torch::zeros({ static_cast(vsamples.size() + 1), static_cast(vsamples[0].size()) }, torch::kInt32)) , className(className) + , features(features) , classNumStates(classNumStates) - , samples(torch::zeros({ static_cast(vsamples.size() + 1), static_cast(vsamples[0].size()) }, torch::kInt32)) { for (int i = 0; i < vsamples.size(); ++i) { samples.index_put_({ i, "..." }, torch::tensor(vsamples[i], torch::kInt32)); @@ -105,14 +105,6 @@ namespace bayesnet { } return matrix; } - // To use in Python - std::vector Metrics::conditionalEdgeWeights(std::vector& weights_) - { - const torch::Tensor weights = torch::tensor(weights_); - auto matrix = conditionalEdge(weights); - std::vector v(matrix.data_ptr(), matrix.data_ptr() + matrix.numel()); - return v; - } double Metrics::entropy(const torch::Tensor& feature, const torch::Tensor& weights) { torch::Tensor counts = feature.bincount(weights); diff --git a/bayesnet/utils/BayesMetrics.h b/bayesnet/utils/BayesMetrics.h index aa8b0d5..2665e73 100644 --- a/bayesnet/utils/BayesMetrics.h +++ b/bayesnet/utils/BayesMetrics.h @@ -18,7 +18,6 @@ namespace bayesnet { std::vector SelectKBestWeighted(const torch::Tensor& weights, bool ascending = false, unsigned k = 0); std::vector getScoresKBest() const; double mutualInformation(const torch::Tensor& firstFeature, const torch::Tensor& secondFeature, const torch::Tensor& weights); - std::vector conditionalEdgeWeights(std::vector& weights); // To use in Python torch::Tensor conditionalEdge(const torch::Tensor& weights); std::vector> maximumSpanningTree(const std::vector& features, const torch::Tensor& weights, const int root); protected: diff --git a/docs/coverage.pdf b/docs/coverage.pdf new file mode 100644 index 0000000..582c2b9 Binary files /dev/null and b/docs/coverage.pdf differ diff --git a/tests/TestBoostAODE.cc b/tests/TestBoostAODE.cc index f6bf5fa..105155b 100644 --- a/tests/TestBoostAODE.cc +++ b/tests/TestBoostAODE.cc @@ -140,21 +140,20 @@ TEST_CASE("Oddities", "[BoostAODE]") TEST_CASE("Bisection Best", "[BoostAODE]") { auto clf = bayesnet::BoostAODE(); - auto raw = RawDatasets("mfeat-factors", true, 300, true); + auto raw = RawDatasets("kdd_JapaneseVowels", true, 1200, true, false); clf.setHyperparameters({ {"bisection", true}, {"maxTolerance", 3}, {"convergence", true}, {"block_update", false}, - {"convergence_best", true}, + {"convergence_best", false}, }); clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states); - REQUIRE(clf.getNumberOfNodes() == 434); - REQUIRE(clf.getNumberOfEdges() == 862); - REQUIRE(clf.getNotes().size() == 3); - REQUIRE(clf.getNotes()[0] == "Convergence threshold reached & 15 models eliminated"); - REQUIRE(clf.getNotes()[1] == "Used features in train: 16 of 216"); - REQUIRE(clf.getNotes()[2] == "Number of models: 1"); + REQUIRE(clf.getNumberOfNodes() == 75); + REQUIRE(clf.getNumberOfEdges() == 135); + REQUIRE(clf.getNotes().size() == 2); + REQUIRE(clf.getNotes().at(0) == "Convergence threshold reached & 9 models eliminated"); + REQUIRE(clf.getNotes().at(1) == "Number of models: 5"); auto score = clf.score(raw.X_test, raw.y_test); auto scoret = clf.score(raw.X_test, raw.y_test); REQUIRE(score == Catch::Approx(1.0f).epsilon(raw.epsilon)); @@ -162,11 +161,9 @@ TEST_CASE("Bisection Best", "[BoostAODE]") } TEST_CASE("Bisection Best vs Last", "[BoostAODE]") { - auto raw = RawDatasets("mfeat-factors", true, 500); + auto raw = RawDatasets("kdd_JapaneseVowels", true, 1500, true, false); auto clf = bayesnet::BoostAODE(true); auto hyperparameters = nlohmann::json{ - {"select_features", "IWSS"}, - {"threshold", 0.5}, {"bisection", true}, {"maxTolerance", 3}, {"convergence", true}, @@ -175,13 +172,13 @@ TEST_CASE("Bisection Best vs Last", "[BoostAODE]") clf.setHyperparameters(hyperparameters); clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states); auto score_best = clf.score(raw.X_test, raw.y_test); - REQUIRE(score_best == Catch::Approx(1.0f).epsilon(raw.epsilon)); + REQUIRE(score_best == Catch::Approx(0.993355f).epsilon(raw.epsilon)); // Now we will set the hyperparameter to use the last accuracy hyperparameters["convergence_best"] = false; clf.setHyperparameters(hyperparameters); clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states); auto score_last = clf.score(raw.X_test, raw.y_test); - REQUIRE(score_last == Catch::Approx(1.0f).epsilon(raw.epsilon)); + REQUIRE(score_last == Catch::Approx(0.996678f).epsilon(raw.epsilon)); } TEST_CASE("Block Update", "[BoostAODE]") @@ -195,14 +192,22 @@ TEST_CASE("Block Update", "[BoostAODE]") {"convergence", true}, }); clf.fit(raw.X_train, raw.y_train, raw.features, raw.className, raw.states); - REQUIRE(clf.getNumberOfNodes() == 217); - REQUIRE(clf.getNumberOfEdges() == 431); + REQUIRE(clf.getNumberOfNodes() == 868); + REQUIRE(clf.getNumberOfEdges() == 1724); REQUIRE(clf.getNotes().size() == 3); REQUIRE(clf.getNotes()[0] == "Convergence threshold reached & 15 models eliminated"); - REQUIRE(clf.getNotes()[1] == "Used features in train: 16 of 216"); - REQUIRE(clf.getNotes()[2] == "Number of models: 1"); + REQUIRE(clf.getNotes()[1] == "Used features in train: 19 of 216"); + REQUIRE(clf.getNotes()[2] == "Number of models: 4"); auto score = clf.score(raw.X_test, raw.y_test); auto scoret = clf.score(raw.X_test, raw.y_test); - REQUIRE(score == Catch::Approx(1.0f).epsilon(raw.epsilon)); - REQUIRE(scoret == Catch::Approx(1.0f).epsilon(raw.epsilon)); + REQUIRE(score == Catch::Approx(0.99f).epsilon(raw.epsilon)); + REQUIRE(scoret == Catch::Approx(0.99f).epsilon(raw.epsilon)); + // + // std::cout << "Number of nodes " << clf.getNumberOfNodes() << std::endl; + // std::cout << "Number of edges " << clf.getNumberOfEdges() << std::endl; + // std::cout << "Notes size " << clf.getNotes().size() << std::endl; + // for (auto note : clf.getNotes()) { + // std::cout << note << std::endl; + // } + // std::cout << "Score " << score << std::endl; } \ No newline at end of file diff --git a/tests/TestUtils.cc b/tests/TestUtils.cc index 3439145..597250d 100644 --- a/tests/TestUtils.cc +++ b/tests/TestUtils.cc @@ -18,23 +18,23 @@ public: class ShuffleArffFiles : public ArffFiles { public: - ShuffleArffFiles(int num_lines = 0, bool shuffle = false) : ArffFiles(), num_lines(num_lines), shuffle(shuffle) {} + ShuffleArffFiles(int num_samples = 0, bool shuffle = false) : ArffFiles(), num_samples(num_samples), shuffle(shuffle) {} void load(const std::string& file_name, bool class_last = true) { ArffFiles::load(file_name, class_last); - if (num_lines > 0) { - if (num_lines > getY().size()) { + if (num_samples > 0) { + if (num_samples > getY().size()) { throw std::invalid_argument("num_lines must be less than the number of lines in the file"); } - auto indices = std::vector(num_lines); + auto indices = std::vector(num_samples); std::iota(indices.begin(), indices.end(), 0); if (shuffle) { std::mt19937 g{ 173 }; std::shuffle(indices.begin(), indices.end(), g); } - auto XX = std::vector>(attributes.size(), std::vector(num_lines)); - auto yy = std::vector(num_lines); - for (int i = 0; i < num_lines; i++) { + auto XX = std::vector>(attributes.size(), std::vector(num_samples)); + auto yy = std::vector(num_samples); + for (int i = 0; i < num_samples; i++) { yy[i] = getY()[indices[i]]; for (int j = 0; j < attributes.size(); j++) { XX[j][i] = X[j][indices[i]]; @@ -45,18 +45,18 @@ public: } } private: - int num_lines; + int num_samples; bool shuffle; }; -RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num_lines_, bool shuffle_) +RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num_samples_, bool shuffle_, bool class_last, bool debug) { - num_lines = num_lines_; + num_samples = num_samples_; shuffle = shuffle_; discretize = discretize_; // Xt can be either discretized or not // Xv is always discretized - loadDataset(file_name); + loadDataset(file_name, class_last); auto yresized = torch::transpose(yt.view({ yt.size(0), 1 }), 0, 1); dataset = torch::cat({ Xt, yresized }, 0); nSamples = dataset.size(1); @@ -72,7 +72,8 @@ RawDatasets::RawDatasets(const std::string& file_name, bool discretize_, int num y_train = dataset.index({ -1, train_t }); X_test = dataset.index({ torch::indexing::Slice(0, dataset.size(0) - 1), test_t }); y_test = dataset.index({ -1, test_t }); - std::cout << to_string(); + if (debug) + std::cout << to_string(); } map RawDatasets::discretizeDataset(std::vector& X) @@ -89,10 +90,10 @@ map RawDatasets::discretizeDataset(std::vector(name) + ".arff", true); + auto handler = ShuffleArffFiles(num_samples, shuffle); + handler.load(Paths::datasets() + static_cast(name) + ".arff", class_last); // Get Dataset X, y std::vector& X = handler.getX(); yv = handler.getY(); diff --git a/tests/TestUtils.h b/tests/TestUtils.h index c3a17c3..09ea305 100644 --- a/tests/TestUtils.h +++ b/tests/TestUtils.h @@ -18,7 +18,7 @@ class RawDatasets { public: - RawDatasets(const std::string& file_name, bool discretize_, int num_lines_ = 0, bool shuffle_ = false); + RawDatasets(const std::string& file_name, bool discretize_, int num_samples_ = 0, bool shuffle_ = false, bool class_last = true, bool debug = false); torch::Tensor Xt, yt, dataset, weights; torch::Tensor X_train, y_train, X_test, y_test; std::vector> Xv; @@ -30,7 +30,7 @@ public: int nSamples, classNumStates; double epsilon = 1e-5; bool discretize; - int num_lines = 0; + int num_samples = 0; bool shuffle = false; private: std::string to_string() @@ -62,11 +62,9 @@ private: + "nSamples: " + std::to_string(nSamples) + "\n" + "classNumStates: " + std::to_string(classNumStates) + "\n" + "states: " + states_ + "\n"; - - } map discretizeDataset(std::vector& X); - void loadDataset(const std::string& name); + void loadDataset(const std::string& name, bool class_last); }; #endif //TEST_UTILS_H \ No newline at end of file diff --git a/tests/lib/catch2/.github/workflows/mac-builds-m1.yml b/tests/lib/catch2/.github/workflows/mac-builds-m1.yml new file mode 100644 index 0000000..4820466 --- /dev/null +++ b/tests/lib/catch2/.github/workflows/mac-builds-m1.yml @@ -0,0 +1,44 @@ +name: M1 Mac builds + +on: [push, pull_request] + +jobs: + build: + runs-on: macos-14 + strategy: + matrix: + cxx: + - clang++ + build_type: [Debug, Release] + std: [14, 17] + include: + - build_type: Debug + examples: ON + extra_tests: ON + + steps: + - uses: actions/checkout@v4 + + - name: Configure build + working-directory: ${{runner.workspace}} + env: + CXX: ${{matrix.cxx}} + CXXFLAGS: ${{matrix.cxxflags}} + run: | + cmake -Bbuild -H$GITHUB_WORKSPACE \ + -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCATCH_DEVELOPMENT_BUILD=ON \ + -DCATCH_BUILD_EXAMPLES=${{matrix.examples}} \ + -DCATCH_BUILD_EXTRA_TESTS=${{matrix.examples}} + + - name: Build tests + lib + working-directory: ${{runner.workspace}}/build + run: make -j `sysctl -n hw.ncpu` + + - name: Run tests + env: + CTEST_OUTPUT_ON_FAILURE: 1 + working-directory: ${{runner.workspace}}/build + run: ctest -C ${{matrix.build_type}} -j `sysctl -n hw.ncpu` diff --git a/tests/lib/catch2/.gitignore b/tests/lib/catch2/.gitignore index 4ed76b0..be955e6 100644 --- a/tests/lib/catch2/.gitignore +++ b/tests/lib/catch2/.gitignore @@ -27,6 +27,7 @@ benchmark-dir .conan/test_package/build .conan/test_package/CMakeUserPresets.json bazel-* +MODULE.bazel.lock build-fuzzers debug-build .vscode diff --git a/tests/lib/catch2/CMakeLists.txt b/tests/lib/catch2/CMakeLists.txt index ce225c0..958d382 100644 --- a/tests/lib/catch2/CMakeLists.txt +++ b/tests/lib/catch2/CMakeLists.txt @@ -33,7 +33,7 @@ if (CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) endif() project(Catch2 - VERSION 3.5.3 # CML version placeholder, don't delete + VERSION 3.5.4 # CML version placeholder, don't delete LANGUAGES CXX # HOMEPAGE_URL is not supported until CMake version 3.12, which # we do not target yet. @@ -76,8 +76,6 @@ endif() set(CATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(SOURCES_DIR ${CATCH_DIR}/src/catch2) set(SELF_TEST_DIR ${CATCH_DIR}/tests/SelfTest) -set(BENCHMARK_DIR ${CATCH_DIR}/tests/Benchmark) -set(EXAMPLES_DIR ${CATCH_DIR}/examples) # We need to bring-in the variables defined there to this scope add_subdirectory(src) diff --git a/tests/lib/catch2/conanfile.py b/tests/lib/catch2/conanfile.py index 8f45b8a..7a3ac7c 100755 --- a/tests/lib/catch2/conanfile.py +++ b/tests/lib/catch2/conanfile.py @@ -19,6 +19,7 @@ class CatchConan(ConanFile): license = "BSL-1.0" version = "latest" settings = "os", "compiler", "build_type", "arch" + extension_properties = {"compatibility_cppstd": False} options = { "shared": [True, False], @@ -115,6 +116,7 @@ class CatchConan(ConanFile): # Catch2 self.cpp_info.components["catch2base"].set_property("cmake_file_name", "Catch2::Catch2") + self.cpp_info.components["catch2base"].set_property("cmake_target_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") diff --git a/tests/lib/catch2/docs/release-notes.md b/tests/lib/catch2/docs/release-notes.md index b462b01..87cec24 100644 --- a/tests/lib/catch2/docs/release-notes.md +++ b/tests/lib/catch2/docs/release-notes.md @@ -2,6 +2,7 @@ # Release notes **Contents**
+[3.5.4](#354)
[3.5.3](#353)
[3.5.2](#352)
[3.5.1](#351)
@@ -61,6 +62,29 @@ [Even Older versions](#even-older-versions)
+## 3.5.4 + +### Fixes +* Fixed potential compilation error when asked to generate random integers whose type did not match `std::(u)int*_t`. + * This manifested itself when generating random `size_t`s on MacOS +* Added missing outlined destructor causing `Wdelete-incomplete` when compiling against libstdc++ in C++23 mode (#2852) +* Fixed regression where decomposing assertion with const instance of `std::foo_ordering` would not compile + +### Improvements +* Reintroduced support for GCC 5 and 6 (#2836) + * As with VS2017, if they start causing trouble again, they will be dropped again. +* Added workaround for targetting newest MacOS (Sonoma) using GCC (#2837, #2839) +* `CATCH_CONFIG_DEFAULT_REPORTER` can now be an arbitrary reporter spec + * Previously it could only be a plain reporter name, so it was impossible to compile in custom arguments to the reporter. +* Improved performance of generating 64bit random integers by 20+% + +### Miscellaneous +* Significantly improved Conan in-tree recipe (#2831) +* `DL_PATHS` in `catch_discover_tests` now supports multiple arguments (#2852, #2736) +* Fixed preprocessor logic for checking whether we expect reproducible floating point results in tests. +* Improved the floating point tests structure to avoid `Wunused` when the reproducibility tests are disabled (#2845) + + ## 3.5.3 ### Fixes diff --git a/tests/lib/catch2/examples/CMakeLists.txt b/tests/lib/catch2/examples/CMakeLists.txt index 82734ad..7e629e0 100644 --- a/tests/lib/catch2/examples/CMakeLists.txt +++ b/tests/lib/catch2/examples/CMakeLists.txt @@ -43,8 +43,7 @@ set( TARGETS_IDIOMATIC_EXAMPLES ${BASENAMES_IDIOMATIC_EXAMPLES} ) foreach( name ${TARGETS_IDIOMATIC_EXAMPLES} ) - add_executable( ${name} - ${EXAMPLES_DIR}/${name}.cpp ) + add_executable( ${name} ${name}.cpp ) endforeach() set(ALL_EXAMPLE_TARGETS diff --git a/tests/lib/catch2/extras/catch_amalgamated.cpp b/tests/lib/catch2/extras/catch_amalgamated.cpp index c3fbc06..6aa6788 100644 --- a/tests/lib/catch2/extras/catch_amalgamated.cpp +++ b/tests/lib/catch2/extras/catch_amalgamated.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.5.3 -// Generated: 2024-03-01 22:05:56.038084 +// Catch v3.5.4 +// Generated: 2024-04-10 12:03:46.281848 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -187,7 +187,7 @@ namespace Catch { double const* last, Estimator& estimator ) { auto n = static_cast( last - first ); - std::uniform_int_distribution dist( 0, n - 1 ); + Catch::uniform_integer_distribution dist( 0, n - 1 ); sample out; out.reserve( resamples ); @@ -807,14 +807,16 @@ namespace Catch { // Insert the default reporter if user hasn't asked for a specific one if ( m_data.reporterSpecifications.empty() ) { - m_data.reporterSpecifications.push_back( { #if defined( CATCH_CONFIG_DEFAULT_REPORTER ) - CATCH_CONFIG_DEFAULT_REPORTER, + const auto default_spec = CATCH_CONFIG_DEFAULT_REPORTER; #else - "console", + const auto default_spec = "console"; #endif - {}, {}, {} - } ); + auto parsed = parseReporterSpec(default_spec); + CATCH_ENFORCE( parsed, + "Cannot parse the provided default reporter spec: '" + << default_spec << '\'' ); + m_data.reporterSpecifications.push_back( std::move( *parsed ) ); } if ( enableBazelEnvSupport() ) { @@ -2271,7 +2273,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 5, 3, "", 0 ); + static Version version( 3, 5, 4, "", 0 ); return version; } @@ -6601,6 +6603,8 @@ namespace Catch { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } + TestRegistry::~TestRegistry() = default; + void TestRegistry::registerTest(Detail::unique_ptr testInfo, Detail::unique_ptr testInvoker) { m_handles.emplace_back(testInfo.get(), testInvoker.get()); m_viewed_test_infos.push_back(testInfo.get()); diff --git a/tests/lib/catch2/extras/catch_amalgamated.hpp b/tests/lib/catch2/extras/catch_amalgamated.hpp index e575431..7e75a5d 100644 --- a/tests/lib/catch2/extras/catch_amalgamated.hpp +++ b/tests/lib/catch2/extras/catch_amalgamated.hpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: BSL-1.0 -// Catch v3.5.3 -// Generated: 2024-03-01 22:05:55.031514 +// Catch v3.5.4 +// Generated: 2024-04-10 12:03:45.785902 // ---------------------------------------------------------- // This file is an amalgamation of multiple different files. // You probably shouldn't edit it directly. @@ -87,6 +87,9 @@ // See e.g.: // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ +# ifndef __has_extension +# define __has_extension(x) 0 +# endif # include # if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) @@ -5254,6 +5257,12 @@ namespace Detail { namespace Catch { + namespace Detail { + // This was added in C++20, but we require only C++14 for now. + template + using RemoveCVRef_t = std::remove_cv_t>; + } + // 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 @@ -5293,14 +5302,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 ); @@ -5406,17 +5414,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -5425,7 +5433,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -5439,7 +5447,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -5460,17 +5468,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -5479,7 +5487,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -5491,7 +5499,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -5512,16 +5520,16 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ - !capture_by_value>::value, \ + -> std::enable_if_t< \ + !capture_by_value>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t::value, \ - BinaryExpr> { \ + -> std::enable_if_t::value, \ + BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } @@ -5553,8 +5561,7 @@ namespace Catch { struct Decomposer { template >::value, + std::enable_if_t>::value, int> = 0> constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs { return ExprLhs{ lhs }; @@ -7263,7 +7270,7 @@ namespace Catch { #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 5 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_PATCH 4 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED @@ -7935,6 +7942,32 @@ namespace Catch { #include #include +// Note: We use the usual enable-disable-autodetect dance here even though +// we do not support these in CMake configuration options (yet?). +// It is highly unlikely that we will need to make these actually +// user-configurable, but this will make it simpler if weend up needing +// it, and it provides an escape hatch to the users who need it. +#if defined( __SIZEOF_INT128__ ) +# define CATCH_CONFIG_INTERNAL_UINT128 +#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) ) +# define CATCH_CONFIG_INTERNAL_MSVC_UMUL128 +#endif + +#if defined( CATCH_CONFIG_INTERNAL_UINT128 ) && \ + !defined( CATCH_CONFIG_NO_UINT128 ) && \ + !defined( CATCH_CONFIG_UINT128 ) +#define CATCH_CONFIG_UINT128 +#endif + +#if defined( CATCH_CONFIG_INTERNAL_MSVC_UMUL128 ) && \ + !defined( CATCH_CONFIG_NO_MSVC_UMUL128 ) && \ + !defined( CATCH_CONFIG_MSVC_UMUL128 ) +# define CATCH_CONFIG_MSVC_UMUL128 +# include +# pragma intrinsic( _umul128 ) +#endif + + namespace Catch { namespace Detail { @@ -7967,59 +8000,52 @@ namespace Catch { } }; - // Returns 128 bit result of multiplying lhs and rhs + /** + * Returns 128 bit result of lhs * rhs using portable C++ code + * + * This implementation is almost twice as fast as naive long multiplication, + * and unlike intrinsic-based approach, it supports constexpr evaluation. + */ constexpr ExtendedMultResult - extendedMult( std::uint64_t lhs, std::uint64_t rhs ) { - // We use the simple long multiplication approach for - // correctness, we can use platform specific builtins - // for performance later. - - // Split the lhs and rhs into two 32bit "digits", so that we can - // do 64 bit arithmetic to handle carry bits. - // 32b 32b 32b 32b - // lhs L1 L2 - // * rhs R1 R2 - // ------------------------ - // | R2 * L2 | - // | R2 * L1 | - // | R1 * L2 | - // | R1 * L1 | - // ------------------------- - // | a | b | c | d | - + extendedMultPortable(std::uint64_t lhs, std::uint64_t rhs) { #define CarryBits( x ) ( x >> 32 ) #define Digits( x ) ( x & 0xFF'FF'FF'FF ) + std::uint64_t lhs_low = Digits( lhs ); + std::uint64_t rhs_low = Digits( rhs ); + std::uint64_t low_low = ( lhs_low * rhs_low ); + std::uint64_t high_high = CarryBits( lhs ) * CarryBits( rhs ); - auto r2l2 = Digits( rhs ) * Digits( lhs ); - auto r2l1 = Digits( rhs ) * CarryBits( lhs ); - auto r1l2 = CarryBits( rhs ) * Digits( lhs ); - auto r1l1 = CarryBits( rhs ) * CarryBits( lhs ); - - // Sum to columns first - auto d = Digits( r2l2 ); - auto c = CarryBits( r2l2 ) + Digits( r2l1 ) + Digits( r1l2 ); - auto b = CarryBits( r2l1 ) + CarryBits( r1l2 ) + Digits( r1l1 ); - auto a = CarryBits( r1l1 ); - - // Propagate carries between columns - c += CarryBits( d ); - b += CarryBits( c ); - a += CarryBits( b ); - - // Remove the used carries - c = Digits( c ); - b = Digits( b ); - a = Digits( a ); + // We add in carry bits from low-low already + std::uint64_t high_low = + ( CarryBits( lhs ) * rhs_low ) + CarryBits( low_low ); + // Note that we can add only low bits from high_low, to avoid + // overflow with large inputs + std::uint64_t low_high = + ( lhs_low * CarryBits( rhs ) ) + Digits( high_low ); + return { high_high + CarryBits( high_low ) + CarryBits( low_high ), + ( low_high << 32 ) | Digits( low_low ) }; #undef CarryBits #undef Digits - - return { - a << 32 | b, // upper 64 bits - c << 32 | d // lower 64 bits - }; } + //! Returns 128 bit result of lhs * rhs + inline ExtendedMultResult + extendedMult( std::uint64_t lhs, std::uint64_t rhs ) { +#if defined( CATCH_CONFIG_UINT128 ) + auto result = __uint128_t( lhs ) * __uint128_t( rhs ); + return { static_cast( result >> 64 ), + static_cast( result ) }; +#elif defined( CATCH_CONFIG_MSVC_UMUL128 ) + std::uint64_t high; + std::uint64_t low = _umul128( lhs, rhs, &high ); + return { high, low }; +#else + return extendedMultPortable( lhs, rhs ); +#endif + } + + template constexpr ExtendedMultResult extendedMult( UInt lhs, UInt rhs ) { static_assert( std::is_unsigned::value, @@ -8123,22 +8149,6 @@ namespace Catch { namespace Catch { - namespace Detail { - // Indirection to enable make_unsigned behaviour. - template - struct make_unsigned { - using type = std::make_unsigned_t; - }; - - template <> - struct make_unsigned { - using type = uint8_t; - }; - - template - using make_unsigned_t = typename make_unsigned::type; - } - /** * Implementation of uniform distribution on integers. * @@ -8154,7 +8164,7 @@ template class uniform_integer_distribution { static_assert(std::is_integral::value, "..."); - using UnsignedIntegerType = Detail::make_unsigned_t; + using UnsignedIntegerType = Detail::SizedUnsignedType_t; // Only the left bound is stored, and we store it converted to its // unsigned image. This avoids having to do the conversions inside @@ -10823,6 +10833,8 @@ namespace Catch { std::vector const& getAllTests() const override; std::vector const& getAllTestsSorted( IConfig const& config ) const override; + ~TestRegistry() override; // = default + private: std::vector> m_owned_test_infos; // Keeps a materialized vector for `getAllInfos`. diff --git a/tests/lib/catch2/meson.build b/tests/lib/catch2/meson.build index 3d0e715..7c216f9 100644 --- a/tests/lib/catch2/meson.build +++ b/tests/lib/catch2/meson.build @@ -8,7 +8,7 @@ project( 'catch2', 'cpp', - version: '3.5.3', # CML version placeholder, don't delete + version: '3.5.4', # CML version placeholder, don't delete license: 'BSL-1.0', meson_version: '>=0.54.1', ) diff --git a/tests/lib/catch2/src/catch2/catch_version.cpp b/tests/lib/catch2/src/catch2/catch_version.cpp index 2604be3..9e8765b 100644 --- a/tests/lib/catch2/src/catch2/catch_version.cpp +++ b/tests/lib/catch2/src/catch2/catch_version.cpp @@ -36,7 +36,7 @@ namespace Catch { } Version const& libraryVersion() { - static Version version( 3, 5, 3, "", 0 ); + static Version version( 3, 5, 4, "", 0 ); return version; } diff --git a/tests/lib/catch2/src/catch2/catch_version_macros.hpp b/tests/lib/catch2/src/catch2/catch_version_macros.hpp index 921ff52..ff50c09 100644 --- a/tests/lib/catch2/src/catch2/catch_version_macros.hpp +++ b/tests/lib/catch2/src/catch2/catch_version_macros.hpp @@ -10,6 +10,6 @@ #define CATCH_VERSION_MAJOR 3 #define CATCH_VERSION_MINOR 5 -#define CATCH_VERSION_PATCH 3 +#define CATCH_VERSION_PATCH 4 #endif // CATCH_VERSION_MACROS_HPP_INCLUDED diff --git a/tests/lib/catch2/src/catch2/internal/catch_decomposer.hpp b/tests/lib/catch2/src/catch2/internal/catch_decomposer.hpp index 143ee3d..41365b7 100644 --- a/tests/lib/catch2/src/catch2/internal/catch_decomposer.hpp +++ b/tests/lib/catch2/src/catch2/internal/catch_decomposer.hpp @@ -125,6 +125,12 @@ namespace Catch { + namespace Detail { + // This was added in C++20, but we require only C++14 for now. + template + using RemoveCVRef_t = std::remove_cv_t>; + } + // 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 @@ -276,17 +282,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_EQUALITY_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -295,7 +301,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -309,7 +315,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_eq_0_comparable, \ @@ -330,17 +336,17 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_COMPARISON_OPERATOR( id, op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ Detail::negation>>>::value, \ + Detail::RemoveCVRef_t>>>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction, \ capture_by_value>::value, \ BinaryExpr> { \ @@ -349,7 +355,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -361,7 +367,7 @@ namespace Catch { } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t< \ + -> std::enable_if_t< \ Detail::conjunction< \ Detail::negation>, \ Detail::is_##id##_0_comparable, \ @@ -382,16 +388,16 @@ namespace Catch { #define CATCH_INTERNAL_DEFINE_EXPRESSION_OPERATOR( op ) \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT&& rhs ) \ - ->std::enable_if_t< \ - !capture_by_value>::value, \ + -> std::enable_if_t< \ + !capture_by_value>::value, \ BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } \ template \ constexpr friend auto operator op( ExprLhs&& lhs, RhsT rhs ) \ - ->std::enable_if_t::value, \ - BinaryExpr> { \ + -> std::enable_if_t::value, \ + BinaryExpr> { \ return { \ static_cast( lhs.m_lhs op rhs ), lhs.m_lhs, #op##_sr, rhs }; \ } @@ -423,8 +429,7 @@ namespace Catch { struct Decomposer { template >::value, + std::enable_if_t>::value, int> = 0> constexpr friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs { return ExprLhs{ lhs }; diff --git a/tests/lib/catch2/src/catch2/internal/catch_random_integer_helpers.hpp b/tests/lib/catch2/src/catch2/internal/catch_random_integer_helpers.hpp index 10d8255..cb5e004 100644 --- a/tests/lib/catch2/src/catch2/internal/catch_random_integer_helpers.hpp +++ b/tests/lib/catch2/src/catch2/internal/catch_random_integer_helpers.hpp @@ -21,7 +21,10 @@ // it, and it provides an escape hatch to the users who need it. #if defined( __SIZEOF_INT128__ ) # define CATCH_CONFIG_INTERNAL_UINT128 -#elif defined( _MSC_VER ) && ( defined( _WIN64 ) || defined( _M_ARM64 ) ) +// Unlike GCC, MSVC does not polyfill umul as mulh + mul pair on ARM machines. +// Currently we do not bother doing this ourselves, but we could if it became +// important for perf. +#elif defined( _MSC_VER ) && defined( _M_X64 ) # define CATCH_CONFIG_INTERNAL_MSVC_UMUL128 #endif @@ -36,7 +39,6 @@ !defined( CATCH_CONFIG_MSVC_UMUL128 ) # define CATCH_CONFIG_MSVC_UMUL128 # include -# pragma intrinsic( _umul128 ) #endif diff --git a/tests/lib/catch2/src/catch2/internal/catch_run_context.cpp b/tests/lib/catch2/src/catch2/internal/catch_run_context.cpp index 77b476d..0769178 100644 --- a/tests/lib/catch2/src/catch2/internal/catch_run_context.cpp +++ b/tests/lib/catch2/src/catch2/internal/catch_run_context.cpp @@ -450,6 +450,13 @@ namespace Catch { assertionEnded(CATCH_MOVE(result) ); resetAssertionInfo(); + // Best effort cleanup for sections that have not been destructed yet + // Since this is a fatal error, we have not had and won't have the opportunity to destruct them properly + while (!m_activeSections.empty()) { + auto nl = m_activeSections.back()->nameAndLocation(); + SectionEndInfo endInfo{ SectionInfo(CATCH_MOVE(nl.location), CATCH_MOVE(nl.name)), {}, 0.0 }; + sectionEndedEarly(CATCH_MOVE(endInfo)); + } handleUnfinishedSections(); // Recreate section for test case (as we will lose the one that was in scope) diff --git a/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.cpp b/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.cpp index c2b052d..e77e7bc 100644 --- a/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.cpp +++ b/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.cpp @@ -123,6 +123,8 @@ namespace Catch { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } + TestRegistry::~TestRegistry() = default; + void TestRegistry::registerTest(Detail::unique_ptr testInfo, Detail::unique_ptr testInvoker) { m_handles.emplace_back(testInfo.get(), testInvoker.get()); m_viewed_test_infos.push_back(testInfo.get()); diff --git a/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.hpp b/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.hpp index 99a3849..fbca89f 100644 --- a/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.hpp +++ b/tests/lib/catch2/src/catch2/internal/catch_test_case_registry_impl.hpp @@ -36,6 +36,8 @@ namespace Catch { std::vector const& getAllTests() const override; std::vector const& getAllTestsSorted( IConfig const& config ) const override; + ~TestRegistry() override; // = default + private: std::vector> m_owned_test_infos; // Keeps a materialized vector for `getAllInfos`. diff --git a/tests/lib/catch2/src/catch2/matchers/catch_matchers_floating_point.cpp b/tests/lib/catch2/src/catch2/matchers/catch_matchers_floating_point.cpp index 206332e..fc7b444 100644 --- a/tests/lib/catch2/src/catch2/matchers/catch_matchers_floating_point.cpp +++ b/tests/lib/catch2/src/catch2/matchers/catch_matchers_floating_point.cpp @@ -176,7 +176,7 @@ namespace Detail { std::string WithinRelMatcher::describe() const { Catch::ReusableStringStream sstr; - sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other"; + sstr << "and " << ::Catch::Detail::stringify(m_target) << " are within " << m_epsilon * 100. << "% of each other"; return sstr.str(); } diff --git a/tests/lib/catch2/tests/BUILD.bazel b/tests/lib/catch2/tests/BUILD.bazel new file mode 100644 index 0000000..5f0362f --- /dev/null +++ b/tests/lib/catch2/tests/BUILD.bazel @@ -0,0 +1,83 @@ +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "catch2_self_test_helper", + srcs = ["SelfTest/helpers/parse_test_spec.cpp"], + hdrs = [ + "SelfTest/helpers/parse_test_spec.hpp", + "SelfTest/helpers/range_test_helpers.hpp", + "SelfTest/helpers/type_with_lit_0_comparisons.hpp", + ], + includes = ["SelfTest"], + deps = [ + "//:catch2", + ], +) + +cc_test( + name = "catch2_self_test", + size = "small", + srcs = [ + "SelfTest/IntrospectiveTests/Algorithms.tests.cpp", + "SelfTest/IntrospectiveTests/Clara.tests.cpp", + "SelfTest/IntrospectiveTests/CmdLine.tests.cpp", + "SelfTest/IntrospectiveTests/CmdLineHelpers.tests.cpp", + "SelfTest/IntrospectiveTests/ColourImpl.tests.cpp", + "SelfTest/IntrospectiveTests/Details.tests.cpp", + "SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp", + "SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp", + "SelfTest/IntrospectiveTests/Integer.tests.cpp", + "SelfTest/IntrospectiveTests/InternalBenchmark.tests.cpp", + "SelfTest/IntrospectiveTests/Parse.tests.cpp", + "SelfTest/IntrospectiveTests/PartTracker.tests.cpp", + "SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp", + "SelfTest/IntrospectiveTests/Reporters.tests.cpp", + "SelfTest/IntrospectiveTests/Sharding.tests.cpp", + "SelfTest/IntrospectiveTests/Stream.tests.cpp", + "SelfTest/IntrospectiveTests/String.tests.cpp", + "SelfTest/IntrospectiveTests/StringManip.tests.cpp", + "SelfTest/IntrospectiveTests/Tag.tests.cpp", + "SelfTest/IntrospectiveTests/TestCaseInfoHasher.tests.cpp", + "SelfTest/IntrospectiveTests/TestSpec.tests.cpp", + "SelfTest/IntrospectiveTests/TestSpecParser.tests.cpp", + "SelfTest/IntrospectiveTests/TextFlow.tests.cpp", + "SelfTest/IntrospectiveTests/ToString.tests.cpp", + "SelfTest/IntrospectiveTests/Traits.tests.cpp", + "SelfTest/IntrospectiveTests/UniquePtr.tests.cpp", + "SelfTest/IntrospectiveTests/Xml.tests.cpp", + "SelfTest/TestRegistrations.cpp", + "SelfTest/TimingTests/Sleep.tests.cpp", + "SelfTest/UsageTests/Approx.tests.cpp", + "SelfTest/UsageTests/BDD.tests.cpp", + "SelfTest/UsageTests/Benchmark.tests.cpp", + "SelfTest/UsageTests/Class.tests.cpp", + "SelfTest/UsageTests/Compilation.tests.cpp", + "SelfTest/UsageTests/Condition.tests.cpp", + "SelfTest/UsageTests/Decomposition.tests.cpp", + "SelfTest/UsageTests/EnumToString.tests.cpp", + "SelfTest/UsageTests/Exception.tests.cpp", + "SelfTest/UsageTests/Generators.tests.cpp", + "SelfTest/UsageTests/Matchers.tests.cpp", + "SelfTest/UsageTests/MatchersRanges.tests.cpp", + "SelfTest/UsageTests/Message.tests.cpp", + "SelfTest/UsageTests/Misc.tests.cpp", + "SelfTest/UsageTests/ToStringByte.tests.cpp", + "SelfTest/UsageTests/ToStringChrono.tests.cpp", + "SelfTest/UsageTests/ToStringGeneral.tests.cpp", + "SelfTest/UsageTests/ToStringOptional.tests.cpp", + "SelfTest/UsageTests/ToStringPair.tests.cpp", + "SelfTest/UsageTests/ToStringTuple.tests.cpp", + "SelfTest/UsageTests/ToStringVariant.tests.cpp", + "SelfTest/UsageTests/ToStringVector.tests.cpp", + "SelfTest/UsageTests/ToStringWhich.tests.cpp", + "SelfTest/UsageTests/Tricky.tests.cpp", + "SelfTest/UsageTests/VariadicMacros.tests.cpp", + ], + deps = [ + ":catch2_self_test_helper", + "//:catch2", + "//:catch2_main", + ], +) diff --git a/tests/lib/catch2/tests/ExtraTests/CMakeLists.txt b/tests/lib/catch2/tests/ExtraTests/CMakeLists.txt index 8eaf3a5..9f6d817 100644 --- a/tests/lib/catch2/tests/ExtraTests/CMakeLists.txt +++ b/tests/lib/catch2/tests/ExtraTests/CMakeLists.txt @@ -467,6 +467,18 @@ set_tests_properties( PASS_REGULAR_EXPRESSION "Errors occurred during startup!" ) +add_executable(ReportingCrashWithJunitReporter ${TESTS_DIR}/X36-ReportingCrashWithJunitReporter.cpp) +target_link_libraries(ReportingCrashWithJunitReporter PRIVATE Catch2::Catch2WithMain) +add_test( + NAME Reporters::CrashInJunitReporter + COMMAND ${CMAKE_COMMAND} -E env $ --reporter JUnit +) +set_tests_properties( + Reporters::CrashInJunitReporter + PROPERTIES + PASS_REGULAR_EXPRESSION "" + LABELS "uses-signals" +) add_executable(AssertionStartingEventGoesBeforeAssertionIsEvaluated X20-AssertionStartingEventGoesBeforeAssertionIsEvaluated.cpp diff --git a/tests/lib/catch2/tests/ExtraTests/X36-ReportingCrashWithJunitReporter.cpp b/tests/lib/catch2/tests/ExtraTests/X36-ReportingCrashWithJunitReporter.cpp new file mode 100644 index 0000000..34f4cd8 --- /dev/null +++ b/tests/lib/catch2/tests/ExtraTests/X36-ReportingCrashWithJunitReporter.cpp @@ -0,0 +1,32 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +/**\file + * Checks that signals/SEH within open section does not hard crash JUnit + * (or similar reporter) while we are trying to report fatal error. + */ + +#include + +#include + +// On Windows we need to send SEH and not signal to test the +// RunContext::handleFatalErrorCondition code path +#if defined( _MSC_VER ) +# include +#endif + +TEST_CASE( "raises signal" ) { + SECTION( "section" ) { +#if defined( _MSC_VER ) + RaiseException( 0xC0000005, 0, 0, NULL ); +#else + std::raise( SIGILL ); +#endif + } +} diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.approved.txt index 037d7e9..a0d8349 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -598,9 +598,9 @@ Misc.tests.cpp:: passed: Factorial(10) == 3628800 for: 3628800 (0x< GeneratorsImpl.tests.cpp:: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException Matchers.tests.cpp:: passed: 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other Matchers.tests.cpp:: passed: 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other -Matchers.tests.cpp:: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other -Matchers.tests.cpp:: passed: -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other -Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other +Matchers.tests.cpp:: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other +Matchers.tests.cpp:: passed: -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other +Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other Matchers.tests.cpp:: passed: 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0 Matchers.tests.cpp:: passed: 0., WithinAbs( 1., 1 ) for: 0.0 is within 1.0 of 1.0 Matchers.tests.cpp:: passed: 0., !WithinAbs( 1., 0.99 ) for: 0.0 not is within 0.99 of 1.0 @@ -618,7 +618,7 @@ Matchers.tests.cpp:: passed: 1., WithinULP( 1., 0 ) for: 1.0 is wit Matchers.tests.cpp:: passed: -0., WithinULP( 0., 0 ) for: -0.0 is within 0 ULPs of 0.0000000000000000e+00 ([0.0000000000000000e+00, 0.0000000000000000e+00]) Matchers.tests.cpp:: passed: 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0000000000000000e+00 ([1.9999999999999998e+00, 2.0000000000000004e+00]) ) Matchers.tests.cpp:: passed: 1., WithinAbs( 2., 0.5 ) || WithinULP( 1., 0 ) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) ) -Matchers.tests.cpp:: passed: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +Matchers.tests.cpp:: passed: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) Matchers.tests.cpp:: passed: WithinAbs( 1., 0. ) Matchers.tests.cpp:: passed: WithinAbs( 1., -1. ), std::domain_error Matchers.tests.cpp:: passed: WithinULP( 1., 0 ) @@ -626,11 +626,11 @@ Matchers.tests.cpp:: passed: WithinRel( 1., 0. ) Matchers.tests.cpp:: passed: WithinRel( 1., -0.2 ), std::domain_error Matchers.tests.cpp:: passed: WithinRel( 1., 1. ), std::domain_error Matchers.tests.cpp:: passed: 1., !IsNaN() for: 1.0 not is NaN -Matchers.tests.cpp:: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other -Matchers.tests.cpp:: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other -Matchers.tests.cpp:: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other -Matchers.tests.cpp:: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other -Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other +Matchers.tests.cpp:: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other +Matchers.tests.cpp:: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other +Matchers.tests.cpp:: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other +Matchers.tests.cpp:: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other +Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other Matchers.tests.cpp:: passed: 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0 Matchers.tests.cpp:: passed: 0.f, WithinAbs( 1.f, 1 ) for: 0.0f is within 1.0 of 1.0 Matchers.tests.cpp:: passed: 0.f, !WithinAbs( 1.f, 0.99f ) for: 0.0f not is within 0.9900000095 of 1.0 @@ -650,7 +650,7 @@ Matchers.tests.cpp:: passed: 1.f, WithinULP( 1.f, 0 ) for: 1.0f is Matchers.tests.cpp:: passed: -0.f, WithinULP( 0.f, 0 ) for: -0.0f is within 0 ULPs of 0.00000000e+00f ([0.00000000e+00, 0.00000000e+00]) Matchers.tests.cpp:: passed: 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00]) ) Matchers.tests.cpp:: passed: 1.f, WithinAbs( 2.f, 0.5 ) || WithinULP( 1.f, 0 ) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) ) -Matchers.tests.cpp:: passed: 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +Matchers.tests.cpp:: passed: 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) Matchers.tests.cpp:: passed: WithinAbs( 1.f, 0.f ) Matchers.tests.cpp:: passed: WithinAbs( 1.f, -1.f ), std::domain_error Matchers.tests.cpp:: passed: WithinULP( 1.f, 0 ) diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.multi.approved.txt index b26546c..4008382 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.multi.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/compact.sw.multi.approved.txt @@ -596,9 +596,9 @@ Misc.tests.cpp:: passed: Factorial(10) == 3628800 for: 3628800 (0x< GeneratorsImpl.tests.cpp:: passed: filter( []( int ) { return false; }, value( 3 ) ), Catch::GeneratorException Matchers.tests.cpp:: passed: 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% of each other Matchers.tests.cpp:: passed: 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other -Matchers.tests.cpp:: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other -Matchers.tests.cpp:: passed: -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other -Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other +Matchers.tests.cpp:: passed: 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other +Matchers.tests.cpp:: passed: -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other +Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other Matchers.tests.cpp:: passed: 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0 Matchers.tests.cpp:: passed: 0., WithinAbs( 1., 1 ) for: 0.0 is within 1.0 of 1.0 Matchers.tests.cpp:: passed: 0., !WithinAbs( 1., 0.99 ) for: 0.0 not is within 0.99 of 1.0 @@ -616,7 +616,7 @@ Matchers.tests.cpp:: passed: 1., WithinULP( 1., 0 ) for: 1.0 is wit Matchers.tests.cpp:: passed: -0., WithinULP( 0., 0 ) for: -0.0 is within 0 ULPs of 0.0000000000000000e+00 ([0.0000000000000000e+00, 0.0000000000000000e+00]) Matchers.tests.cpp:: passed: 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0000000000000000e+00 ([1.9999999999999998e+00, 2.0000000000000004e+00]) ) Matchers.tests.cpp:: passed: 1., WithinAbs( 2., 0.5 ) || WithinULP( 1., 0 ) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) ) -Matchers.tests.cpp:: passed: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +Matchers.tests.cpp:: passed: 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) Matchers.tests.cpp:: passed: WithinAbs( 1., 0. ) Matchers.tests.cpp:: passed: WithinAbs( 1., -1. ), std::domain_error Matchers.tests.cpp:: passed: WithinULP( 1., 0 ) @@ -624,11 +624,11 @@ Matchers.tests.cpp:: passed: WithinRel( 1., 0. ) Matchers.tests.cpp:: passed: WithinRel( 1., -0.2 ), std::domain_error Matchers.tests.cpp:: passed: WithinRel( 1., 1. ), std::domain_error Matchers.tests.cpp:: passed: 1., !IsNaN() for: 1.0 not is NaN -Matchers.tests.cpp:: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other -Matchers.tests.cpp:: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other -Matchers.tests.cpp:: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other -Matchers.tests.cpp:: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other -Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other +Matchers.tests.cpp:: passed: 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other +Matchers.tests.cpp:: passed: 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other +Matchers.tests.cpp:: passed: 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other +Matchers.tests.cpp:: passed: -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other +Matchers.tests.cpp:: passed: v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other Matchers.tests.cpp:: passed: 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0 Matchers.tests.cpp:: passed: 0.f, WithinAbs( 1.f, 1 ) for: 0.0f is within 1.0 of 1.0 Matchers.tests.cpp:: passed: 0.f, !WithinAbs( 1.f, 0.99f ) for: 0.0f not is within 0.9900000095 of 1.0 @@ -648,7 +648,7 @@ Matchers.tests.cpp:: passed: 1.f, WithinULP( 1.f, 0 ) for: 1.0f is Matchers.tests.cpp:: passed: -0.f, WithinULP( 0.f, 0 ) for: -0.0f is within 0 ULPs of 0.00000000e+00f ([0.00000000e+00, 0.00000000e+00]) Matchers.tests.cpp:: passed: 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.00000000e+00f ([9.99999940e-01, 1.00000012e+00]) ) Matchers.tests.cpp:: passed: 1.f, WithinAbs( 2.f, 0.5 ) || WithinULP( 1.f, 0 ) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) ) -Matchers.tests.cpp:: passed: 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +Matchers.tests.cpp:: passed: 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) Matchers.tests.cpp:: passed: WithinAbs( 1.f, 0.f ) Matchers.tests.cpp:: passed: WithinAbs( 1.f, -1.f ), std::domain_error Matchers.tests.cpp:: passed: WithinULP( 1.f, 0 ) diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.approved.txt index a14ead1..2424ea1 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.approved.txt @@ -4487,12 +4487,12 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 1., !WithinRel( 0., 0.99 ) ) with expansion: - 1.0 not and 0 are within 99% of each other + 1.0 not and 0.0 are within 99% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( -0., WithinRel( 0. ) ) with expansion: - -0.0 and 0 are within 2.22045e-12% of each other + -0.0 and 0.0 are within 2.22045e-12% of each other ------------------------------------------------------------------------------- Floating point matchers: double @@ -4505,7 +4505,7 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( v1, WithinRel( v2 ) ) with expansion: - 0.0 and 2.22507e-308 are within 2.22045e-12% of each other + 0.0 and 0.0 are within 2.22045e-12% of each other ------------------------------------------------------------------------------- Floating point matchers: double @@ -4625,7 +4625,7 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) ) with expansion: - 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) ------------------------------------------------------------------------------- Floating point matchers: double @@ -4674,22 +4674,22 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 10.f, WithinRel( 11.1f, 0.1f ) ) with expansion: - 10.0f and 11.1 are within 10% of each other + 10.0f and 11.1000003815 are within 10% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 10.f, !WithinRel( 11.2f, 0.1f ) ) with expansion: - 10.0f not and 11.2 are within 10% of each other + 10.0f not and 11.1999998093 are within 10% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 1.f, !WithinRel( 0.f, 0.99f ) ) with expansion: - 1.0f not and 0 are within 99% of each other + 1.0f not and 0.0 are within 99% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( -0.f, WithinRel( 0.f ) ) with expansion: - -0.0f and 0 are within 0.00119209% of each other + -0.0f and 0.0 are within 0.00119209% of each other ------------------------------------------------------------------------------- Floating point matchers: float @@ -4702,7 +4702,7 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( v1, WithinRel( v2 ) ) with expansion: - 0.0f and 1.17549e-38 are within 0.00119209% of each other + 0.0f and 0.0 are within 0.00119209% of each other ------------------------------------------------------------------------------- Floating point matchers: float @@ -4827,7 +4827,7 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) ) with expansion: - 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) ------------------------------------------------------------------------------- Floating point matchers: float diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.multi.approved.txt index b706c56..e8fd62f 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -4485,12 +4485,12 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 1., !WithinRel( 0., 0.99 ) ) with expansion: - 1.0 not and 0 are within 99% of each other + 1.0 not and 0.0 are within 99% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( -0., WithinRel( 0. ) ) with expansion: - -0.0 and 0 are within 2.22045e-12% of each other + -0.0 and 0.0 are within 2.22045e-12% of each other ------------------------------------------------------------------------------- Floating point matchers: double @@ -4503,7 +4503,7 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( v1, WithinRel( v2 ) ) with expansion: - 0.0 and 2.22507e-308 are within 2.22045e-12% of each other + 0.0 and 0.0 are within 2.22045e-12% of each other ------------------------------------------------------------------------------- Floating point matchers: double @@ -4623,7 +4623,7 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) ) with expansion: - 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) ------------------------------------------------------------------------------- Floating point matchers: double @@ -4672,22 +4672,22 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 10.f, WithinRel( 11.1f, 0.1f ) ) with expansion: - 10.0f and 11.1 are within 10% of each other + 10.0f and 11.1000003815 are within 10% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 10.f, !WithinRel( 11.2f, 0.1f ) ) with expansion: - 10.0f not and 11.2 are within 10% of each other + 10.0f not and 11.1999998093 are within 10% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 1.f, !WithinRel( 0.f, 0.99f ) ) with expansion: - 1.0f not and 0 are within 99% of each other + 1.0f not and 0.0 are within 99% of each other Matchers.tests.cpp:: PASSED: REQUIRE_THAT( -0.f, WithinRel( 0.f ) ) with expansion: - -0.0f and 0 are within 0.00119209% of each other + -0.0f and 0.0 are within 0.00119209% of each other ------------------------------------------------------------------------------- Floating point matchers: float @@ -4700,7 +4700,7 @@ Matchers.tests.cpp: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( v1, WithinRel( v2 ) ) with expansion: - 0.0f and 1.17549e-38 are within 0.00119209% of each other + 0.0f and 0.0 are within 0.00119209% of each other ------------------------------------------------------------------------------- Floating point matchers: float @@ -4825,7 +4825,7 @@ with expansion: Matchers.tests.cpp:: PASSED: REQUIRE_THAT( 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) ) with expansion: - 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) ------------------------------------------------------------------------------- Floating point matchers: float diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.approved.txt index 7ece3f8..d9d3459 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -1129,11 +1129,11 @@ ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% # Floating point matchers: double ok {test-number} - 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other # Floating point matchers: double -ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other +ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other # Floating point matchers: double -ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other +ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other # Floating point matchers: double -ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other +ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other # Floating point matchers: double ok {test-number} - 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0 # Floating point matchers: double @@ -1169,7 +1169,7 @@ ok {test-number} - 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is # Floating point matchers: double ok {test-number} - 1., WithinAbs( 2., 0.5 ) || WithinULP( 1., 0 ) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) ) # Floating point matchers: double -ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) # Floating point matchers: double ok {test-number} - WithinAbs( 1., 0. ) # Floating point matchers: double @@ -1185,15 +1185,15 @@ ok {test-number} - WithinRel( 1., 1. ), std::domain_error # Floating point matchers: double ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN # Floating point matchers: float -ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other +ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other # Floating point matchers: float -ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other +ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other # Floating point matchers: float -ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other +ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other # Floating point matchers: float -ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other +ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other # Floating point matchers: float -ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other +ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other # Floating point matchers: float ok {test-number} - 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0 # Floating point matchers: float @@ -1233,7 +1233,7 @@ ok {test-number} - 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f ( # Floating point matchers: float ok {test-number} - 1.f, WithinAbs( 2.f, 0.5 ) || WithinULP( 1.f, 0 ) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) ) # Floating point matchers: float -ok {test-number} - 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +ok {test-number} - 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) # Floating point matchers: float ok {test-number} - WithinAbs( 1.f, 0.f ) # Floating point matchers: float diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index 2dfcb65..a439fde 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -1127,11 +1127,11 @@ ok {test-number} - 10., WithinRel( 11.1, 0.1 ) for: 10.0 and 11.1 are within 10% # Floating point matchers: double ok {test-number} - 10., !WithinRel( 11.2, 0.1 ) for: 10.0 not and 11.2 are within 10% of each other # Floating point matchers: double -ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0 are within 99% of each other +ok {test-number} - 1., !WithinRel( 0., 0.99 ) for: 1.0 not and 0.0 are within 99% of each other # Floating point matchers: double -ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0 are within 2.22045e-12% of each other +ok {test-number} - -0., WithinRel( 0. ) for: -0.0 and 0.0 are within 2.22045e-12% of each other # Floating point matchers: double -ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 2.22507e-308 are within 2.22045e-12% of each other +ok {test-number} - v1, WithinRel( v2 ) for: 0.0 and 0.0 are within 2.22045e-12% of each other # Floating point matchers: double ok {test-number} - 1., WithinAbs( 1., 0 ) for: 1.0 is within 0.0 of 1.0 # Floating point matchers: double @@ -1167,7 +1167,7 @@ ok {test-number} - 1., WithinAbs( 1., 0.5 ) || WithinULP( 2., 1 ) for: 1.0 ( is # Floating point matchers: double ok {test-number} - 1., WithinAbs( 2., 0.5 ) || WithinULP( 1., 0 ) for: 1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0000000000000000e+00 ([1.0000000000000000e+00, 1.0000000000000000e+00]) ) # Floating point matchers: double -ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +ok {test-number} - 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) for: 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) # Floating point matchers: double ok {test-number} - WithinAbs( 1., 0. ) # Floating point matchers: double @@ -1183,15 +1183,15 @@ ok {test-number} - WithinRel( 1., 1. ), std::domain_error # Floating point matchers: double ok {test-number} - 1., !IsNaN() for: 1.0 not is NaN # Floating point matchers: float -ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1 are within 10% of each other +ok {test-number} - 10.f, WithinRel( 11.1f, 0.1f ) for: 10.0f and 11.1000003815 are within 10% of each other # Floating point matchers: float -ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.2 are within 10% of each other +ok {test-number} - 10.f, !WithinRel( 11.2f, 0.1f ) for: 10.0f not and 11.1999998093 are within 10% of each other # Floating point matchers: float -ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0 are within 99% of each other +ok {test-number} - 1.f, !WithinRel( 0.f, 0.99f ) for: 1.0f not and 0.0 are within 99% of each other # Floating point matchers: float -ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0 are within 0.00119209% of each other +ok {test-number} - -0.f, WithinRel( 0.f ) for: -0.0f and 0.0 are within 0.00119209% of each other # Floating point matchers: float -ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 1.17549e-38 are within 0.00119209% of each other +ok {test-number} - v1, WithinRel( v2 ) for: 0.0f and 0.0 are within 0.00119209% of each other # Floating point matchers: float ok {test-number} - 1.f, WithinAbs( 1.f, 0 ) for: 1.0f is within 0.0 of 1.0 # Floating point matchers: float @@ -1231,7 +1231,7 @@ ok {test-number} - 1.f, WithinAbs( 1.f, 0.5 ) || WithinULP( 1.f, 1 ) for: 1.0f ( # Floating point matchers: float ok {test-number} - 1.f, WithinAbs( 2.f, 0.5 ) || WithinULP( 1.f, 0 ) for: 1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.00000000e+00f ([1.00000000e+00, 1.00000000e+00]) ) # Floating point matchers: float -ok {test-number} - 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) +ok {test-number} - 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) for: 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) # Floating point matchers: float ok {test-number} - WithinAbs( 1.f, 0.f ) # Floating point matchers: float diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.approved.txt index 01af9ed..e3a6dc0 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -5022,7 +5022,7 @@ C 1., !WithinRel( 0., 0.99 ) - 1.0 not and 0 are within 99% of each other + 1.0 not and 0.0 are within 99% of each other @@ -5030,7 +5030,7 @@ C -0., WithinRel( 0. ) - -0.0 and 0 are within 2.22045e-12% of each other + -0.0 and 0.0 are within 2.22045e-12% of each other
@@ -5039,7 +5039,7 @@ C v1, WithinRel( v2 ) - 0.0 and 2.22507e-308 are within 2.22045e-12% of each other + 0.0 and 0.0 are within 2.22045e-12% of each other @@ -5194,7 +5194,7 @@ C 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) - 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) @@ -5270,7 +5270,7 @@ C 10.f, WithinRel( 11.1f, 0.1f ) - 10.0f and 11.1 are within 10% of each other + 10.0f and 11.1000003815 are within 10% of each other @@ -5278,7 +5278,7 @@ C 10.f, !WithinRel( 11.2f, 0.1f ) - 10.0f not and 11.2 are within 10% of each other + 10.0f not and 11.1999998093 are within 10% of each other @@ -5286,7 +5286,7 @@ C 1.f, !WithinRel( 0.f, 0.99f ) - 1.0f not and 0 are within 99% of each other + 1.0f not and 0.0 are within 99% of each other @@ -5294,7 +5294,7 @@ C -0.f, WithinRel( 0.f ) - -0.0f and 0 are within 0.00119209% of each other + -0.0f and 0.0 are within 0.00119209% of each other
@@ -5303,7 +5303,7 @@ C v1, WithinRel( v2 ) - 0.0f and 1.17549e-38 are within 0.00119209% of each other + 0.0f and 0.0 are within 0.00119209% of each other @@ -5474,7 +5474,7 @@ C 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) - 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) diff --git a/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index 6c50a99..62a2740 100644 --- a/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/lib/catch2/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -5022,7 +5022,7 @@ C 1., !WithinRel( 0., 0.99 ) - 1.0 not and 0 are within 99% of each other + 1.0 not and 0.0 are within 99% of each other @@ -5030,7 +5030,7 @@ C -0., WithinRel( 0. ) - -0.0 and 0 are within 2.22045e-12% of each other + -0.0 and 0.0 are within 2.22045e-12% of each other
@@ -5039,7 +5039,7 @@ C v1, WithinRel( v2 ) - 0.0 and 2.22507e-308 are within 2.22045e-12% of each other + 0.0 and 0.0 are within 2.22045e-12% of each other @@ -5194,7 +5194,7 @@ C 0.0001, WithinAbs( 0., 0.001 ) || WithinRel( 0., 0.1 ) - 0.0001 ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001 ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) @@ -5270,7 +5270,7 @@ C 10.f, WithinRel( 11.1f, 0.1f ) - 10.0f and 11.1 are within 10% of each other + 10.0f and 11.1000003815 are within 10% of each other @@ -5278,7 +5278,7 @@ C 10.f, !WithinRel( 11.2f, 0.1f ) - 10.0f not and 11.2 are within 10% of each other + 10.0f not and 11.1999998093 are within 10% of each other @@ -5286,7 +5286,7 @@ C 1.f, !WithinRel( 0.f, 0.99f ) - 1.0f not and 0 are within 99% of each other + 1.0f not and 0.0 are within 99% of each other @@ -5294,7 +5294,7 @@ C -0.f, WithinRel( 0.f ) - -0.0f and 0 are within 0.00119209% of each other + -0.0f and 0.0 are within 0.00119209% of each other
@@ -5303,7 +5303,7 @@ C v1, WithinRel( v2 ) - 0.0f and 1.17549e-38 are within 0.00119209% of each other + 0.0f and 0.0 are within 0.00119209% of each other @@ -5474,7 +5474,7 @@ C 0.0001f, WithinAbs( 0.f, 0.001f ) || WithinRel( 0.f, 0.1f ) - 0.0001f ( is within 0.001 of 0.0 or and 0 are within 10% of each other ) + 0.0001f ( is within 0.001 of 0.0 or and 0.0 are within 10% of each other ) diff --git a/tests/lib/catch2/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp b/tests/lib/catch2/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp index 327b65e..8932321 100644 --- a/tests/lib/catch2/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp +++ b/tests/lib/catch2/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp @@ -495,6 +495,22 @@ TEMPLATE_TEST_CASE( "uniform_integer_distribution is reproducible", REQUIRE_THAT(generated, Catch::Matchers::RangeEquals(uniform_integer_test_params::expected)); } +// 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( __i386__ ) || defined( __x86_64__ ) ) ) && \ + !defined( __SSE2_MATH__ ) ) +# define CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS +#endif + +#if !defined( CATCH_TEST_CONFIG_DISABLE_FLOAT_REPRODUCIBILITY_TESTS ) + namespace { template struct uniform_fp_test_params; @@ -552,20 +568,6 @@ 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, @@ -596,7 +598,7 @@ TEMPLATE_TEST_CASE( "uniform_floating_point_distribution can handle unitary rang CAPTURE( seed ); Catch::SimplePcg32 pcg( seed ); - const auto highest = uniform_fp_test_params::highest; + const auto highest = TestType(385.125); Catch::uniform_floating_point_distribution dist( highest, highest ); diff --git a/tests/lib/catch2/tests/SelfTest/UsageTests/Compilation.tests.cpp b/tests/lib/catch2/tests/SelfTest/UsageTests/Compilation.tests.cpp index 46ccb8b..a7fbf08 100644 --- a/tests/lib/catch2/tests/SelfTest/UsageTests/Compilation.tests.cpp +++ b/tests/lib/catch2/tests/SelfTest/UsageTests/Compilation.tests.cpp @@ -357,6 +357,12 @@ namespace { constexpr friend bool operator op( ZeroLiteralConsteval, \ TypeWithConstevalLit0Comparison ) { \ return false; \ + } \ + /* std::orderings only have these for ==, but we add them for all \ + operators so we can test all overloads for decomposer */ \ + constexpr friend bool operator op( TypeWithConstevalLit0Comparison, \ + TypeWithConstevalLit0Comparison ) { \ + return true; \ } DEFINE_COMP_OP( < ) @@ -394,6 +400,33 @@ TEST_CASE( "#2555 - types that can only be compared with 0 literal implemented a REQUIRE_FALSE( 0 != TypeWithConstevalLit0Comparison{} ); } +// We check all comparison ops to test, even though orderings, the primary +// motivation for this functionality, only have self-comparison (and thus +// have the ambiguity issue) for `==` and `!=`. +TEST_CASE( "Comparing const instances of type registered with capture_by_value", + "[regression][approvals][compilation]" ) { + SECTION("Type with consteval-int constructor") { + auto const const_Lit0Type_1 = TypeWithConstevalLit0Comparison{}; + auto const const_Lit0Type_2 = TypeWithConstevalLit0Comparison{}; + REQUIRE( const_Lit0Type_1 == const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 <= const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 < const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 >= const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 > const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 != const_Lit0Type_2 ); + } + SECTION("Type with constexpr-int constructor") { + auto const const_Lit0Type_1 = TypeWithLit0Comparisons{}; + auto const const_Lit0Type_2 = TypeWithLit0Comparisons{}; + REQUIRE( const_Lit0Type_1 == const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 <= const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 < const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 >= const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 > const_Lit0Type_2 ); + REQUIRE( const_Lit0Type_1 != const_Lit0Type_2 ); + } +} + #endif // C++20 consteval @@ -420,3 +453,17 @@ TEST_CASE("#2571 - tests compile types that have multiple implicit constructors REQUIRE( mic1 > mic2 ); REQUIRE( mic1 >= mic2 ); } + +#if defined( CATCH_CONFIG_CPP20_COMPARE_OVERLOADS ) +// This test does not test all the related codepaths, but it is the original +// reproducer +TEST_CASE( "Comparing const std::weak_ordering instances must compile", + "[compilation][approvals][regression]" ) { + auto const const_ordering_1 = std::weak_ordering::less; + auto const const_ordering_2 = std::weak_ordering::less; + auto plain_ordering_1 = std::weak_ordering::less; + REQUIRE( const_ordering_1 == plain_ordering_1 ); + REQUIRE( const_ordering_1 == const_ordering_2 ); + REQUIRE( plain_ordering_1 == const_ordering_1 ); +} +#endif diff --git a/tests/lib/catch2/tests/SelfTest/helpers/type_with_lit_0_comparisons.hpp b/tests/lib/catch2/tests/SelfTest/helpers/type_with_lit_0_comparisons.hpp index 88d2f2a..a8e517c 100644 --- a/tests/lib/catch2/tests/SelfTest/helpers/type_with_lit_0_comparisons.hpp +++ b/tests/lib/catch2/tests/SelfTest/helpers/type_with_lit_0_comparisons.hpp @@ -26,14 +26,20 @@ struct ZeroLiteralAsPointer { struct TypeWithLit0Comparisons { -#define DEFINE_COMP_OP( op ) \ - constexpr friend bool operator op( TypeWithLit0Comparisons, \ - ZeroLiteralAsPointer ) { \ - return true; \ - } \ - constexpr friend bool operator op( ZeroLiteralAsPointer, \ - TypeWithLit0Comparisons ) { \ - return false; \ +#define DEFINE_COMP_OP( op ) \ + constexpr friend bool operator op( TypeWithLit0Comparisons, \ + ZeroLiteralAsPointer ) { \ + return true; \ + } \ + constexpr friend bool operator op( ZeroLiteralAsPointer, \ + TypeWithLit0Comparisons ) { \ + return false; \ + } \ + /* std::orderings only have these for ==, but we add them for all \ + operators so we can test all overloads for decomposer */ \ + constexpr friend bool operator op( TypeWithLit0Comparisons, \ + TypeWithLit0Comparisons ) { \ + return true; \ } DEFINE_COMP_OP( < ) diff --git a/tests/lib/catch2/tools/misc/appveyorTestRunScript.bat b/tests/lib/catch2/tools/misc/appveyorTestRunScript.bat index 5982fc9..661bae2 100644 --- a/tests/lib/catch2/tools/misc/appveyorTestRunScript.bat +++ b/tests/lib/catch2/tools/misc/appveyorTestRunScript.bat @@ -5,7 +5,7 @@ reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusion cd Build if "%CONFIGURATION%"=="Debug" ( if "%coverage%"=="1" ( - ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck || exit /b !ERRORLEVEL! + ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck -LE uses-signals || exit /b !ERRORLEVEL! python ..\tools\misc\appveyorMergeCoverageScript.py || exit /b !ERRORLEVEL! codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% || exit /b !ERRORLEVEL! ) else (