diff --git a/include/internal/catch_generators_specific.hpp b/include/internal/catch_generators_specific.hpp index 7985ac70..0734ee78 100644 --- a/include/internal/catch_generators_specific.hpp +++ b/include/internal/catch_generators_specific.hpp @@ -10,6 +10,7 @@ #include "catch_context.h" #include "catch_generators.hpp" #include "catch_interfaces_config.h" +#include "catch_random_number_generator.h" #include @@ -18,14 +19,13 @@ namespace Generators { template class RandomFloatingGenerator final : public IGenerator { - // FIXME: What is the right seed? - std::minstd_rand m_rand; + Catch::SimplePcg32& m_rng; std::uniform_real_distribution m_dist; Float m_current_number; public: RandomFloatingGenerator(Float a, Float b): - m_rand(getCurrentContext().getConfig()->rngSeed()), + m_rng(rng()), m_dist(a, b) { static_cast(next()); } @@ -34,20 +34,20 @@ public: return m_current_number; } bool next() override { - m_current_number = m_dist(m_rand); + m_current_number = m_dist(m_rng); return true; } }; template class RandomIntegerGenerator final : public IGenerator { - std::minstd_rand m_rand; + Catch::SimplePcg32& m_rng; std::uniform_int_distribution m_dist; Integer m_current_number; public: RandomIntegerGenerator(Integer a, Integer b): - m_rand(getCurrentContext().getConfig()->rngSeed()), + m_rng(rng()), m_dist(a, b) { static_cast(next()); } @@ -56,7 +56,7 @@ public: return m_current_number; } bool next() override { - m_current_number = m_dist(m_rand); + m_current_number = m_dist(m_rng); return true; } }; diff --git a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp index dbc1d957..076c91a9 100644 --- a/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp +++ b/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp @@ -250,7 +250,7 @@ int const& TestGen::get() const { } -TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") { +TEST_CASE("GENERATE capture macros", "[generators][internals][approvals]") { auto value = GENERATE(take(10, random(0, 10))); non_copyable nc; nc.value = value; @@ -258,3 +258,28 @@ TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") { auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper(std::unique_ptr>(new TestGen(nc)))); REQUIRE(value == value2); } + +TEST_CASE("Multiple random generators in one test case output different values", "[generators][internals][approvals]") { + SECTION("Integer") { + auto random1 = Catch::Generators::random(0, 1000); + auto random2 = Catch::Generators::random(0, 1000); + size_t same = 0; + for (size_t i = 0; i < 1000; ++i) { + same += random1.get() == random2.get(); + random1.next(); random2.next(); + } + // 0.5% seems like a sane bound for random identical elements within 1000 runs + REQUIRE(same < 5); + } + SECTION("Float") { + auto random1 = Catch::Generators::random(0., 1000.); + auto random2 = Catch::Generators::random(0., 1000.); + size_t same = 0; + for (size_t i = 0; i < 1000; ++i) { + same += random1.get() == random2.get(); + random1.next(); random2.next(); + } + // 0.5% seems like a sane bound for random identical elements within 1000 runs + REQUIRE(same < 5); + } +}