1 // 300-Gen-OwnGenerator.cpp
2 // Shows how to define a custom generator.
3
4 // Specifically we will implement a random number generator for integers
5 // It will have infinite capacity and settable lower/upper bound
6
7 #include <catch2/catch.hpp>
8
9 #include <random>
10
11 // This class shows how to implement a simple generator for Catch tests
12 class RandomIntGenerator : public Catch::Generators::IGenerator<int> {
13 std::minstd_rand m_rand;
14 std::uniform_int_distribution<> m_dist;
15 int current_number;
16 public:
17
RandomIntGenerator(int low,int high)18 RandomIntGenerator(int low, int high):
19 m_rand(std::random_device{}()),
20 m_dist(low, high)
21 {
22 static_cast<void>(next());
23 }
24
25 int const& get() const override;
next()26 bool next() override {
27 current_number = m_dist(m_rand);
28 return true;
29 }
30 };
31
32 // Avoids -Wweak-vtables
get() const33 int const& RandomIntGenerator::get() const {
34 return current_number;
35 }
36
37 // This helper function provides a nicer UX when instantiating the generator
38 // Notice that it returns an instance of GeneratorWrapper<int>, which
39 // is a value-wrapper around std::unique_ptr<IGenerator<int>>.
random(int low,int high)40 Catch::Generators::GeneratorWrapper<int> random(int low, int high) {
41 return Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new RandomIntGenerator(low, high)));
42 }
43
44 // The two sections in this test case are equivalent, but the first one
45 // is much more readable/nicer to use
46 TEST_CASE("Generating random ints", "[example][generator]") {
47 SECTION("Nice UX") {
48 auto i = GENERATE(take(100, random(-100, 100)));
49 REQUIRE(i >= -100);
50 REQUIRE(i <= 100);
51 }
52 SECTION("Creating the random generator directly") {
53 auto i = GENERATE(take(100, GeneratorWrapper<int>(std::unique_ptr<IGenerator<int>>(new RandomIntGenerator(-100, 100)))));
54 REQUIRE(i >= -100);
55 REQUIRE(i <= 100);
56 }
57 }
58
59 // Compiling and running this file will result in 400 successful assertions
60