300-Gen-OwnGenerator.cpp 2.1 KB

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