mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Add GENERATE_COPY and GENERATE_VAR capturing generator macros
This commit is contained in:
		@@ -90,7 +90,11 @@ used with other generators as arguments, such as `auto i = GENERATE(0, 2,
 | 
			
		||||
take(100, random(300, 3000)));`. This is useful e.g. if you know that
 | 
			
		||||
specific inputs are problematic and want to test them separately/first.
 | 
			
		||||
 | 
			
		||||
**For safety reasons, you cannot use variables inside the `GENERATE` macro.**
 | 
			
		||||
**For safety reasons, you cannot use variables inside the `GENERATE` macro.
 | 
			
		||||
This is done because the generator expression _will_ outlive the outside
 | 
			
		||||
scope and thus capturing references is dangerous. If you need to use
 | 
			
		||||
variables inside the generator expression, make sure you thought through
 | 
			
		||||
the lifetime implications and use `GENERATE_COPY` or `GENERATE_REF`.**
 | 
			
		||||
 | 
			
		||||
You can also override the inferred type by using `as<type>` as the first
 | 
			
		||||
argument to the macro. This can be useful when dealing with string literals,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
- Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp)
 | 
			
		||||
- Generators: [Use map to convert types in GENERATE expression](../examples/301-Gen-MapTypeConversion.cpp)
 | 
			
		||||
- Generators: [Use variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp)
 | 
			
		||||
- Generators: [Use custom variable capture in generator expressions](../examples/311-Gen-CustomCapture.cpp)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Planned
 | 
			
		||||
 
 | 
			
		||||
@@ -8,41 +8,6 @@
 | 
			
		||||
 | 
			
		||||
#include <catch2/catch.hpp>
 | 
			
		||||
 | 
			
		||||
#include <random>
 | 
			
		||||
 | 
			
		||||
// Lets start by implementing a parametrizable double generator
 | 
			
		||||
class RandomDoubleGenerator : public Catch::Generators::IGenerator<double> {
 | 
			
		||||
    std::minstd_rand m_rand;
 | 
			
		||||
    std::uniform_real_distribution<> m_dist;
 | 
			
		||||
    double current_number;
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    RandomDoubleGenerator(double low, double high):
 | 
			
		||||
        m_rand(std::random_device{}()),
 | 
			
		||||
        m_dist(low, high)
 | 
			
		||||
    {
 | 
			
		||||
        static_cast<void>(next());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    double const& get() const override;
 | 
			
		||||
    bool next() override {
 | 
			
		||||
        current_number = m_dist(m_rand);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Avoids -Wweak-vtables
 | 
			
		||||
double const& RandomDoubleGenerator::get() const {
 | 
			
		||||
    return current_number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Also provide a nice shortcut for creating the generator
 | 
			
		||||
Catch::Generators::GeneratorWrapper<double> random(double low, double high) {
 | 
			
		||||
    return Catch::Generators::GeneratorWrapper<double>(std::unique_ptr<Catch::Generators::IGenerator<double>>(new RandomDoubleGenerator(low, high)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TEST_CASE("Generate random doubles across different ranges",
 | 
			
		||||
          "[generator][example][advanced]") {
 | 
			
		||||
    // Workaround for old libstdc++
 | 
			
		||||
@@ -55,16 +20,12 @@ TEST_CASE("Generate random doubles across different ranges",
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    // This will not compile (intentionally), because it accesses a variable
 | 
			
		||||
    // auto number = GENERATE(take(50, random(r.first, r.second)));
 | 
			
		||||
    
 | 
			
		||||
    // We have to manually register the generators instead
 | 
			
		||||
    // Notice that we are using value capture in the lambda, to avoid lifetime issues
 | 
			
		||||
    auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO,
 | 
			
		||||
        [=]{
 | 
			
		||||
            using namespace Catch::Generators;
 | 
			
		||||
            return makeGenerators(take(50, random(std::get<0>(r), std::get<1>(r))));
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
    // auto number = GENERATE(take(50, random(std::get<0>(r), std::get<1>(r))));
 | 
			
		||||
 | 
			
		||||
   // GENERATE_COPY copies all variables mentioned inside the expression
 | 
			
		||||
   // thus this will work.
 | 
			
		||||
    auto number = GENERATE_COPY(take(50, random(std::get<0>(r), std::get<1>(r))));
 | 
			
		||||
 | 
			
		||||
    REQUIRE(std::abs(number) > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								examples/311-Gen-CustomCapture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								examples/311-Gen-CustomCapture.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// 311-Gen-CustomCapture.cpp
 | 
			
		||||
// Shows how to provide custom capture list to the generator expression
 | 
			
		||||
 | 
			
		||||
// Note that using variables inside generators is dangerous and should
 | 
			
		||||
// be done only if you know what you are doing, because the generators
 | 
			
		||||
// _WILL_ outlive the variables. Also, even if you know what you are
 | 
			
		||||
// doing, you should probably use GENERATE_COPY or GENERATE_REF macros
 | 
			
		||||
// instead. However, if your use case requires having a
 | 
			
		||||
// per-variable custom capture list, this example shows how to achieve
 | 
			
		||||
// that.
 | 
			
		||||
 | 
			
		||||
#include <catch2/catch.hpp>
 | 
			
		||||
 | 
			
		||||
TEST_CASE("Generate random doubles across different ranges",
 | 
			
		||||
          "[generator][example][advanced]") {
 | 
			
		||||
    // Workaround for old libstdc++
 | 
			
		||||
    using record = std::tuple<double, double>;
 | 
			
		||||
    // Set up 3 ranges to generate numbers from
 | 
			
		||||
    auto r1 = GENERATE(table<double, double>({
 | 
			
		||||
        record{3, 4},
 | 
			
		||||
        record{-4, -3},
 | 
			
		||||
        record{10, 1000}
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    auto r2(r1);
 | 
			
		||||
    
 | 
			
		||||
    // This will take r1 by reference and r2 by value.
 | 
			
		||||
    // Note that there are no advantages for doing so in this example,
 | 
			
		||||
    // it is done only for expository purposes.
 | 
			
		||||
    auto number = Catch::Generators::generate( CATCH_INTERNAL_LINEINFO,
 | 
			
		||||
        [&r1, r2]{
 | 
			
		||||
            using namespace Catch::Generators;
 | 
			
		||||
            return makeGenerators(take(50, random(std::get<0>(r1), std::get<1>(r2))));
 | 
			
		||||
        }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    REQUIRE(std::abs(number) > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compiling and running this file will result in 150 successful assertions
 | 
			
		||||
 | 
			
		||||
@@ -47,6 +47,7 @@ set( SOURCES_IDIOMATIC_TESTS
 | 
			
		||||
    300-Gen-OwnGenerator.cpp
 | 
			
		||||
    301-Gen-MapTypeConversion.cpp
 | 
			
		||||
    310-Gen-VariablesInGenerators.cpp
 | 
			
		||||
    311-Gen-CustomCapture.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# main-s for reporter-specific test sources:
 | 
			
		||||
 
 | 
			
		||||
@@ -201,7 +201,10 @@ namespace Generators {
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#define GENERATE( ... ) \
 | 
			
		||||
    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 | 
			
		||||
 | 
			
		||||
    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 | 
			
		||||
#define GENERATE_COPY( ... ) \
 | 
			
		||||
    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 | 
			
		||||
#define GENERATE_REF( ... ) \
 | 
			
		||||
    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -637,6 +637,22 @@ Matchers.tests.cpp:<line number>: passed: testStringForMatching(), !Contains("di
 | 
			
		||||
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), !Contains("substring") for: "this string contains 'abc' as a substring" not contains: "substring"
 | 
			
		||||
Exception.tests.cpp:<line number>: passed: thisThrows(), "expected exception" for: "expected exception" equals: "expected exception"
 | 
			
		||||
Exception.tests.cpp:<line number>: failed: thisThrows(), "should fail" for: "expected exception" equals: "should fail"
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 3 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 4 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 5 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 6 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: -5 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: -4 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 90 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 91 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 92 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 93 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 94 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 95 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 96 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 97 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 98 > -6
 | 
			
		||||
Generators.tests.cpp:<line number>: passed: values > -6 for: 99 > -6
 | 
			
		||||
Misc.tests.cpp:<line number>: warning: 'This one ran'
 | 
			
		||||
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception'
 | 
			
		||||
Tricky.tests.cpp:<line number>: passed: True for: {?}
 | 
			
		||||
 
 | 
			
		||||
@@ -1264,6 +1264,6 @@ due to unexpected exception with message:
 | 
			
		||||
  Why would you throw a std::string?
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
test cases:  256 |  190 passed |  62 failed |  4 failed as expected
 | 
			
		||||
assertions: 1403 | 1260 passed | 122 failed | 21 failed as expected
 | 
			
		||||
test cases:  257 |  191 passed |  62 failed |  4 failed as expected
 | 
			
		||||
assertions: 1419 | 1276 passed | 122 failed | 21 failed as expected
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4697,6 +4697,182 @@ Exception.tests.cpp:<line number>: FAILED:
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" equals: "should fail"
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  3 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  4 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  5 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  6 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  -5 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  -4 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  90 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  91 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  92 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  93 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  94 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  95 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  96 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  97 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  98 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nested generators and captured variables
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Generators.tests.cpp:<line number>
 | 
			
		||||
...............................................................................
 | 
			
		||||
 | 
			
		||||
Generators.tests.cpp:<line number>: PASSED:
 | 
			
		||||
  REQUIRE( values > -6 )
 | 
			
		||||
with expansion:
 | 
			
		||||
  99 > -6
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nice descriptive name
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
@@ -10936,6 +11112,6 @@ Misc.tests.cpp:<line number>
 | 
			
		||||
Misc.tests.cpp:<line number>: PASSED:
 | 
			
		||||
 | 
			
		||||
===============================================================================
 | 
			
		||||
test cases:  256 |  175 passed |  77 failed |  4 failed as expected
 | 
			
		||||
assertions: 1419 | 1260 passed | 138 failed | 21 failed as expected
 | 
			
		||||
test cases:  257 |  176 passed |  77 failed |  4 failed as expected
 | 
			
		||||
assertions: 1435 | 1276 passed | 138 failed | 21 failed as expected
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
    <property name="random-seed" value="1"/>
 | 
			
		||||
  </properties>
 | 
			
		||||
loose text artifact
 | 
			
		||||
  <testsuite name="<exe-name>" errors="17" failures="122" tests="1420" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
 | 
			
		||||
  <testsuite name="<exe-name>" errors="17" failures="122" tests="1436" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
 | 
			
		||||
@@ -454,6 +454,7 @@ Matchers.tests.cpp:<line number>
 | 
			
		||||
Exception.tests.cpp:<line number>
 | 
			
		||||
      </failure>
 | 
			
		||||
    </testcase>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="Nested generators and captured variables" time="{duration}"/>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="Nice descriptive name" time="{duration}"/>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="Non-std exceptions can be translated" time="{duration}">
 | 
			
		||||
      <error type="TEST_CASE">
 | 
			
		||||
 
 | 
			
		||||
@@ -5913,6 +5913,137 @@ Nor would this
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <OverallResult success="false"/>
 | 
			
		||||
    </TestCase>
 | 
			
		||||
    <TestCase name="Nested generators and captured variables" tags="[generators]" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          3 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          4 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          5 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          6 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          -5 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          -4 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          90 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          91 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          92 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          93 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          94 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          95 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          96 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          97 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          98 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
 | 
			
		||||
        <Original>
 | 
			
		||||
          values > -6
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          99 > -6
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <OverallResult success="true"/>
 | 
			
		||||
    </TestCase>
 | 
			
		||||
    <TestCase name="Nice descriptive name" tags="[.][tag1][tag2][tag3]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
 | 
			
		||||
      <Warning>
 | 
			
		||||
        This one ran
 | 
			
		||||
@@ -13257,7 +13388,7 @@ loose text artifact
 | 
			
		||||
      </Section>
 | 
			
		||||
      <OverallResult success="true"/>
 | 
			
		||||
    </TestCase>
 | 
			
		||||
    <OverallResults successes="1260" failures="139" expectedFailures="21"/>
 | 
			
		||||
    <OverallResults successes="1276" failures="139" expectedFailures="21"/>
 | 
			
		||||
  </Group>
 | 
			
		||||
  <OverallResults successes="1260" failures="138" expectedFailures="21"/>
 | 
			
		||||
  <OverallResults successes="1276" failures="138" expectedFailures="21"/>
 | 
			
		||||
</Catch>
 | 
			
		||||
 
 | 
			
		||||
@@ -216,3 +216,45 @@ TEST_CASE("Generators internals", "[generators][internals]") {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// todo: uncopyable type used in a generator
 | 
			
		||||
//  idea: uncopyable tag type for a stupid generator
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
struct non_copyable {
 | 
			
		||||
    non_copyable() = default;
 | 
			
		||||
    non_copyable(non_copyable const&) = delete;
 | 
			
		||||
    non_copyable& operator=(non_copyable const&) = delete;
 | 
			
		||||
    int value = -1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This class shows how to implement a simple generator for Catch tests
 | 
			
		||||
class TestGen : public Catch::Generators::IGenerator<int> {
 | 
			
		||||
    int current_number;
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    TestGen(non_copyable const& nc):
 | 
			
		||||
        current_number(nc.value) {}
 | 
			
		||||
 | 
			
		||||
    int const& get() const override;
 | 
			
		||||
    bool next() override {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Avoids -Wweak-vtables
 | 
			
		||||
int const& TestGen::get() const {
 | 
			
		||||
    return current_number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE("GENERATE capture macros", "[generators][internals][.approvals]") {
 | 
			
		||||
    auto value = GENERATE(take(10, random(0, 10)));
 | 
			
		||||
 | 
			
		||||
    non_copyable nc; nc.value = value;
 | 
			
		||||
    // neither `GENERATE_COPY` nor plain `GENERATE` would compile here
 | 
			
		||||
    auto value2 = GENERATE_REF(Catch::Generators::GeneratorWrapper<int>(std::unique_ptr<Catch::Generators::IGenerator<int>>(new TestGen(nc))));
 | 
			
		||||
    REQUIRE(value == value2);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -188,3 +188,21 @@ TEST_CASE("Random generator", "[generators][.][approvals]") {
 | 
			
		||||
        static_cast<void>(val); // Silence VS 2015 unused variable warning
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TEST_CASE("Nested generators and captured variables", "[generators]") {
 | 
			
		||||
    // Workaround for old libstdc++
 | 
			
		||||
    using record = std::tuple<int, int>;
 | 
			
		||||
    // Set up 3 ranges to generate numbers from
 | 
			
		||||
    auto extent = GENERATE(table<int, int>({
 | 
			
		||||
        record{3, 7},
 | 
			
		||||
        record{-5, -3},
 | 
			
		||||
        record{90, 100}
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    auto from = std::get<0>(extent);
 | 
			
		||||
    auto to = std::get<1>(extent);
 | 
			
		||||
 | 
			
		||||
    auto values = GENERATE_COPY(range(from, to));
 | 
			
		||||
    REQUIRE(values > -6);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user