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