diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a6b0215..32403f6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,6 +106,7 @@ set(INTERNAL_HEADERS ${SOURCES_DIR}/internal/catch_polyfills.hpp ${SOURCES_DIR}/internal/catch_preprocessor.hpp ${SOURCES_DIR}/internal/catch_random_number_generator.hpp + ${SOURCES_DIR}/internal/catch_random_seed_generation.hpp ${SOURCES_DIR}/catch_reporter_registrars.hpp ${SOURCES_DIR}/internal/catch_reporter_registry.hpp ${SOURCES_DIR}/internal/catch_result_type.hpp @@ -175,6 +176,7 @@ set(IMPL_SOURCES ${SOURCES_DIR}/catch_registry_hub.cpp ${SOURCES_DIR}/internal/catch_combined_tu.cpp ${SOURCES_DIR}/internal/catch_random_number_generator.cpp + ${SOURCES_DIR}/internal/catch_random_seed_generation.cpp ${SOURCES_DIR}/internal/catch_reporter_registry.cpp ${SOURCES_DIR}/internal/catch_result_type.cpp ${SOURCES_DIR}/internal/catch_run_context.cpp diff --git a/src/catch2/catch_all.hpp b/src/catch2/catch_all.hpp index e9fadf96..27282de5 100644 --- a/src/catch2/catch_all.hpp +++ b/src/catch2/catch_all.hpp @@ -80,6 +80,7 @@ #include #include #include +#include #include #include #include diff --git a/src/catch2/internal/catch_random_seed_generation.cpp b/src/catch2/internal/catch_random_seed_generation.cpp new file mode 100644 index 00000000..7fc1b90d --- /dev/null +++ b/src/catch2/internal/catch_random_seed_generation.cpp @@ -0,0 +1,34 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include + +#include + +#include +#include + +namespace Catch { + + std::uint32_t generateRandomSeed( GenerateFrom from ) { + switch ( from ) { + case GenerateFrom::Time: + return static_cast( std::time( nullptr ) ); + + case GenerateFrom::Default: + case GenerateFrom::RandomDevice: + // In theory, a platform could have random_device that returns just + // 16 bits. That is still some randomness, so we don't care too much + return static_cast( std::random_device{}() ); + + default: + CATCH_ERROR("Unknown generation method"); + } + } + +} // end namespace Catch diff --git a/src/catch2/internal/catch_random_seed_generation.hpp b/src/catch2/internal/catch_random_seed_generation.hpp new file mode 100644 index 00000000..42ca93db --- /dev/null +++ b/src/catch2/internal/catch_random_seed_generation.hpp @@ -0,0 +1,26 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED +#define CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED + +#include + +namespace Catch { + + enum class GenerateFrom { + Time, + RandomDevice, + //! Currently equivalent to RandomDevice, but can change at any point + Default + }; + + std::uint32_t generateRandomSeed(GenerateFrom from); + +} // end namespace Catch + +#endif // CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 7b401531..3e9c35f0 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -183,6 +183,8 @@ Nor would this :test-result: PASS Product with differing arities - std::tuple :test-result: PASS Product with differing arities - std::tuple :test-result: PASS Product with differing arities - std::tuple +:test-result: PASS Random seed generation accepts known methods +:test-result: PASS Random seed generation reports unknown methods :test-result: PASS Range type with sentinel :test-result: FAIL Reconstruction should be based on stringification: #914 :test-result: FAIL Regex string matcher diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index 633400ad..6c932221 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -1272,6 +1272,10 @@ CmdLine.tests.cpp:: passed: config.benchmarkWarmupTime == 10 for: 1 Misc.tests.cpp:: passed: std::tuple_size::value >= 1 for: 3 >= 1 Misc.tests.cpp:: passed: std::tuple_size::value >= 1 for: 2 >= 1 Misc.tests.cpp:: passed: std::tuple_size::value >= 1 for: 1 >= 1 +RandomNumberGeneration.tests.cpp:: passed: Catch::generateRandomSeed(method) +RandomNumberGeneration.tests.cpp:: passed: Catch::generateRandomSeed(method) +RandomNumberGeneration.tests.cpp:: passed: Catch::generateRandomSeed(method) +RandomNumberGeneration.tests.cpp:: passed: Catch::generateRandomSeed(static_cast(77)) ToString.tests.cpp:: passed: Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }" Decomposition.tests.cpp:: failed: truthy(false) for: Hey, its truthy! Matchers.tests.cpp:: failed: testStringForMatching(), Matches( "this STRING contains 'abc' as a substring" ) for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index 6c7a58f6..d7639e4d 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1386,6 +1386,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 369 | 293 passed | 70 failed | 6 failed as expected -assertions: 2106 | 1954 passed | 129 failed | 23 failed as expected +test cases: 371 | 295 passed | 70 failed | 6 failed as expected +assertions: 2110 | 1958 passed | 129 failed | 23 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index 8008e9b9..f7ab5b3c 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -9383,6 +9383,42 @@ Misc.tests.cpp:: PASSED: with expansion: 1 >= 1 +------------------------------------------------------------------------------- +Random seed generation accepts known methods +------------------------------------------------------------------------------- +RandomNumberGeneration.tests.cpp: +............................................................................... + +RandomNumberGeneration.tests.cpp:: PASSED: + REQUIRE_NOTHROW( Catch::generateRandomSeed(method) ) + +------------------------------------------------------------------------------- +Random seed generation accepts known methods +------------------------------------------------------------------------------- +RandomNumberGeneration.tests.cpp: +............................................................................... + +RandomNumberGeneration.tests.cpp:: PASSED: + REQUIRE_NOTHROW( Catch::generateRandomSeed(method) ) + +------------------------------------------------------------------------------- +Random seed generation accepts known methods +------------------------------------------------------------------------------- +RandomNumberGeneration.tests.cpp: +............................................................................... + +RandomNumberGeneration.tests.cpp:: PASSED: + REQUIRE_NOTHROW( Catch::generateRandomSeed(method) ) + +------------------------------------------------------------------------------- +Random seed generation reports unknown methods +------------------------------------------------------------------------------- +RandomNumberGeneration.tests.cpp: +............................................................................... + +RandomNumberGeneration.tests.cpp:: PASSED: + REQUIRE_THROWS( Catch::generateRandomSeed(static_cast(77)) ) + ------------------------------------------------------------------------------- Range type with sentinel ------------------------------------------------------------------------------- @@ -16954,6 +16990,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 369 | 277 passed | 86 failed | 6 failed as expected -assertions: 2123 | 1954 passed | 146 failed | 23 failed as expected +test cases: 371 | 279 passed | 86 failed | 6 failed as expected +assertions: 2127 | 1958 passed | 146 failed | 23 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index d4b0b7d7..26afed94 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -1066,6 +1066,8 @@ Message.tests.cpp: + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index d8f09bf9..cb210515 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -152,6 +152,8 @@ + + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index 43af4ca9..d26511c0 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -2466,6 +2466,14 @@ ok {test-number} - std::tuple_size::value >= 1 for: 3 >= 1 ok {test-number} - std::tuple_size::value >= 1 for: 2 >= 1 # Product with differing arities - std::tuple ok {test-number} - std::tuple_size::value >= 1 for: 1 >= 1 +# Random seed generation accepts known methods +ok {test-number} - Catch::generateRandomSeed(method) +# Random seed generation accepts known methods +ok {test-number} - Catch::generateRandomSeed(method) +# Random seed generation accepts known methods +ok {test-number} - Catch::generateRandomSeed(method) +# Random seed generation reports unknown methods +ok {test-number} - Catch::generateRandomSeed(static_cast(77)) # Range type with sentinel ok {test-number} - Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }" # Reconstruction should be based on stringification: #914 @@ -4248,5 +4256,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2123 +1..2127 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index c30de7fd..7b12bd22 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -467,6 +467,10 @@ Message.tests.cpp:|nexplicit failure with message:|n "Message from ##teamcity[testFinished name='Product with differing arities - std::tuple' duration="{duration}"] ##teamcity[testStarted name='Product with differing arities - std::tuple'] ##teamcity[testFinished name='Product with differing arities - std::tuple' duration="{duration}"] +##teamcity[testStarted name='Random seed generation accepts known methods'] +##teamcity[testFinished name='Random seed generation accepts known methods' duration="{duration}"] +##teamcity[testStarted name='Random seed generation reports unknown methods'] +##teamcity[testFinished name='Random seed generation reports unknown methods' duration="{duration}"] ##teamcity[testStarted name='Range type with sentinel'] ##teamcity[testFinished name='Range type with sentinel' duration="{duration}"] ##teamcity[testStarted name='Reconstruction should be based on stringification: #914'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index cba47717..13544d49 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -11468,6 +11468,44 @@ Nor would this + + + + Catch::generateRandomSeed(method) + + + Catch::generateRandomSeed(method) + + + + + Catch::generateRandomSeed(method) + + + Catch::generateRandomSeed(method) + + + + + Catch::generateRandomSeed(method) + + + Catch::generateRandomSeed(method) + + + + + + + + Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77)) + + + Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77)) + + + + @@ -19953,6 +19991,6 @@ loose text artifact - - + + diff --git a/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp b/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp index 3d388c66..d4a36547 100644 --- a/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/RandomNumberGeneration.tests.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") { Catch::SimplePcg32 rng; @@ -40,3 +42,18 @@ TEST_CASE("Comparison ops", "[rng]") { REQUIRE_FALSE(SimplePcg32{ 1 } == SimplePcg32{ 2 }); REQUIRE_FALSE(SimplePcg32{ 1 } != SimplePcg32{ 1 }); } + +TEST_CASE("Random seed generation reports unknown methods", "[rng][seed]") { + REQUIRE_THROWS(Catch::generateRandomSeed(static_cast(77))); +} + +TEST_CASE("Random seed generation accepts known methods", "[rng][seed]") { + using Catch::GenerateFrom; + const auto method = GENERATE( + GenerateFrom::Time, + GenerateFrom::RandomDevice, + GenerateFrom::Default + ); + + REQUIRE_NOTHROW(Catch::generateRandomSeed(method)); +}