mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 00:51:52 +01:00 
			
		
		
		
	
		
			
	
	
		
			60 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			60 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// 300-Gen-OwnGenerator.cpp
							 | 
						||
| 
								 | 
							
								// Shows how to define a custom generator.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Specifically we will implement a random number generator for integers
							 | 
						||
| 
								 | 
							
								// It will have infinite capacity and settable lower/upper bound
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <catch2/catch.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <random>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This class shows how to implement a simple generator for Catch tests
							 | 
						||
| 
								 | 
							
								class RandomIntGenerator : public Catch::Generators::IGenerator<int> {
							 | 
						||
| 
								 | 
							
								    std::minstd_rand m_rand;
							 | 
						||
| 
								 | 
							
								    std::uniform_int_distribution<> m_dist;
							 | 
						||
| 
								 | 
							
								    int current_number;
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RandomIntGenerator(int low, int high):
							 | 
						||
| 
								 | 
							
								        m_rand(std::random_device{}()),
							 | 
						||
| 
								 | 
							
								        m_dist(low, high)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        static_cast<void>(next());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int const& get() const override;
							 | 
						||
| 
								 | 
							
								    bool next() override {
							 | 
						||
| 
								 | 
							
								        current_number = m_dist(m_rand);
							 | 
						||
| 
								 | 
							
								        return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Avoids -Wweak-vtables
							 | 
						||
| 
								 | 
							
								int const& RandomIntGenerator::get() const {
							 | 
						||
| 
								 | 
							
								    return current_number;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This helper function provides a nicer UX when instantiating the generator
							 | 
						||
| 
								 | 
							
								// Notice that it returns an instance of GeneratorWrapper<int>, which
							 | 
						||
| 
								 | 
							
								// is a value-wrapper around std::unique_ptr<IGenerator<int>>.
							 | 
						||
| 
								 | 
							
								Catch::Generators::GeneratorWrapper<int> random(int low, int high) {
							 | 
						||
| 
								 | 
							
								    return Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new RandomIntGenerator(low, high)));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// The two sections in this test case are equivalent, but the first one
							 | 
						||
| 
								 | 
							
								// is much more readable/nicer to use
							 | 
						||
| 
								 | 
							
								TEST_CASE("Generating random ints", "[example][generator]") {
							 | 
						||
| 
								 | 
							
								    SECTION("Nice UX") {
							 | 
						||
| 
								 | 
							
								        auto i = GENERATE(take(100, random(-100, 100)));
							 | 
						||
| 
								 | 
							
								        REQUIRE(i >= -100);
							 | 
						||
| 
								 | 
							
								        REQUIRE(i <= 100);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    SECTION("Creating the random generator directly") {
							 | 
						||
| 
								 | 
							
								        auto i = GENERATE(take(100, GeneratorWrapper<int>(std::unique_ptr<IGenerator<int>>(new RandomIntGenerator(-100, 100)))));
							 | 
						||
| 
								 | 
							
								        REQUIRE(i >= -100);
							 | 
						||
| 
								 | 
							
								        REQUIRE(i <= 100);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Compiling and running this file will result in 400 successful assertions
							 |