mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 03:43:28 +01:00
Have the random generators use the global rng instance
This means that if you nest multiple random generators inside one test case, they will not return the same sequence of numbers. Idea taken from #1736 by Amit Herman. Closes #1736 Closes #1734
This commit is contained in:
parent
535da5c513
commit
a5a22cdadb
@ -10,6 +10,7 @@
|
||||
#include "catch_context.h"
|
||||
#include "catch_generators.hpp"
|
||||
#include "catch_interfaces_config.h"
|
||||
#include "catch_random_number_generator.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
@ -18,14 +19,13 @@ namespace Generators {
|
||||
|
||||
template <typename Float>
|
||||
class RandomFloatingGenerator final : public IGenerator<Float> {
|
||||
// FIXME: What is the right seed?
|
||||
std::minstd_rand m_rand;
|
||||
Catch::SimplePcg32& m_rng;
|
||||
std::uniform_real_distribution<Float> 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<void>(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 <typename Integer>
|
||||
class RandomIntegerGenerator final : public IGenerator<Integer> {
|
||||
std::minstd_rand m_rand;
|
||||
Catch::SimplePcg32& m_rng;
|
||||
std::uniform_int_distribution<Integer> 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<void>(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;
|
||||
}
|
||||
};
|
||||
|
@ -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<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user