| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  | // 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 14:46:07 +01:00
										 |  |  | #include <catch2/catch_test_macros.hpp>
 | 
					
						
							| 
									
										
										
										
											2020-03-30 10:34:21 +02:00
										 |  |  | #include <catch2/generators/catch_generators.hpp>
 | 
					
						
							|  |  |  | #include <catch2/generators/catch_generators_adapters.hpp>
 | 
					
						
							| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <random>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:39:40 +01:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  | // 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) { | 
					
						
							| 
									
										
										
										
											2020-02-01 21:43:00 +01:00
										 |  |  |     return Catch::Generators::GeneratorWrapper<int>( | 
					
						
							| 
									
										
										
										
											2020-05-25 09:45:24 +02:00
										 |  |  |         new RandomIntGenerator(low, high) | 
					
						
							|  |  |  |         // Another possibility:
 | 
					
						
							|  |  |  |         // Catch::Detail::make_unique<RandomIntGenerator>(low, high)
 | 
					
						
							| 
									
										
										
										
											2020-02-01 21:43:00 +01:00
										 |  |  |     ); | 
					
						
							| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 12:39:40 +01:00
										 |  |  | } // end anonymous namespaces
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  | // 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") { | 
					
						
							| 
									
										
										
										
											2020-05-25 09:45:24 +02:00
										 |  |  |         auto i = GENERATE(take(100, GeneratorWrapper<int>(Catch::Detail::make_unique<RandomIntGenerator>(-100, 100)))); | 
					
						
							| 
									
										
										
										
											2019-01-29 10:52:28 +01:00
										 |  |  |         REQUIRE(i >= -100); | 
					
						
							|  |  |  |         REQUIRE(i <= 100); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Compiling and running this file will result in 400 successful assertions
 |