mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 04:07:10 +01:00 
			
		
		
		
	Add a generator that takes an iterator pair
This commit is contained in:
		| @@ -46,13 +46,16 @@ a test case, | ||||
|   * `MapGenerator<T, U, Func>` -- returns the result of applying `Func` | ||||
|   on elements from a different generator | ||||
|   * `ChunkGenerator<T>` -- returns chunks (inside `std::vector`) of n elements from a generator | ||||
| * 3 specific purpose generators | ||||
| * 4 specific purpose generators | ||||
|   * `RandomIntegerGenerator<Integral>` -- generates random Integrals from range | ||||
|   * `RandomFloatGenerator<Float>` -- generates random Floats from range | ||||
|   * `RangeGenerator<T>` -- generates all values inside a specific range | ||||
|   * `IteratorGenerator<T>` -- copies and returns values from an iterator range | ||||
|  | ||||
| > `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch 2.7.0. | ||||
|  | ||||
| > `IteratorGenerator<T>` was introduced in Catch X.Y.Z. | ||||
|  | ||||
| The generators also have associated helper functions that infer their | ||||
| type, making their usage much nicer. These are | ||||
|  | ||||
| @@ -68,9 +71,12 @@ type, making their usage much nicer. These are | ||||
| * `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator` | ||||
| * `range(start, end)` for `RangeGenerator<T>` with a step size of `1` | ||||
| * `range(start, end, step)` for `RangeGenerator<T>` with a custom step size | ||||
| * `from_range(InputIterator from, InputIterator to)` for `IteratorGenerator<T>` | ||||
|  | ||||
| > `chunk()`, `random()` and both `range()` functions were introduced in Catch 2.7.0. | ||||
|  | ||||
| > `from_range` has been introduced in Catch X.Y.Z | ||||
|  | ||||
| And can be used as shown in the example below to create a generator | ||||
| that returns 100 odd random number: | ||||
|  | ||||
|   | ||||
| @@ -128,6 +128,39 @@ GeneratorWrapper<T> range(T const& start, T const& end) { | ||||
| } | ||||
|  | ||||
|  | ||||
| template <typename T> | ||||
| class IteratorGenerator final : public IGenerator<T> { | ||||
|     static_assert(!std::is_same<T, bool>::value, | ||||
|         "IteratorGenerator currently does not support bools" | ||||
|         "because of std::vector<bool> specialization"); | ||||
|  | ||||
|     std::vector<T> m_elems; | ||||
|     size_t m_current = 0; | ||||
| public: | ||||
|     template <typename InputIterator, typename InputSentinel> | ||||
|     IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) { | ||||
|         if (m_elems.empty()) { | ||||
|             Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values")); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     T const& get() const override { | ||||
|         return m_elems[m_current]; | ||||
|     } | ||||
|  | ||||
|     bool next() override { | ||||
|         ++m_current; | ||||
|         return m_current != m_elems.size(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template <typename InputIterator, | ||||
|           typename InputSentinel, | ||||
|           typename ResultType = typename std::iterator_traits<InputIterator>::value_type> | ||||
| GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) { | ||||
|     return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to)); | ||||
| } | ||||
|  | ||||
| } // namespace Generators | ||||
| } // namespace Catch | ||||
|  | ||||
|   | ||||
| @@ -310,6 +310,12 @@ Condition.tests.cpp:<line number>: passed: 6 == uc for: 6 == 6 | ||||
| Condition.tests.cpp:<line number>: passed: (std::numeric_limits<uint32_t>::max)() > ul for: 4294967295 (0x<hex digits>) > 4 | ||||
| Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive) | ||||
| Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("STRING") for: "this string contains 'abc' as a substring" contains: "STRING" | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1 | ||||
| Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom() | ||||
| Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom(), std::exception | ||||
| Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom std exception' | ||||
|   | ||||
| @@ -1380,6 +1380,6 @@ due to unexpected exception with message: | ||||
|   Why would you throw a std::string? | ||||
|  | ||||
| =============================================================================== | ||||
| test cases:  300 |  226 passed |  70 failed |  4 failed as expected | ||||
| assertions: 1564 | 1412 passed | 131 failed | 21 failed as expected | ||||
| test cases:  301 |  227 passed |  70 failed |  4 failed as expected | ||||
| assertions: 1570 | 1418 passed | 131 failed | 21 failed as expected | ||||
|  | ||||
|   | ||||
| @@ -2381,6 +2381,72 @@ Matchers.tests.cpp:<line number>: FAILED: | ||||
| with expansion: | ||||
|   "this string contains 'abc' as a substring" contains: "STRING" | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Copy and then generate a range | ||||
| ------------------------------------------------------------------------------- | ||||
| Generators.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Generators.tests.cpp:<line number>: PASSED: | ||||
|   REQUIRE( elem % 2 == 1 ) | ||||
| with expansion: | ||||
|   1 == 1 | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Custom exceptions can be translated when testing for nothrow | ||||
| ------------------------------------------------------------------------------- | ||||
| @@ -12499,6 +12565,6 @@ Misc.tests.cpp:<line number> | ||||
| Misc.tests.cpp:<line number>: PASSED: | ||||
|  | ||||
| =============================================================================== | ||||
| test cases:  300 |  210 passed |  86 failed |  4 failed as expected | ||||
| assertions: 1581 | 1412 passed | 148 failed | 21 failed as expected | ||||
| test cases:  301 |  211 passed |  86 failed |  4 failed as expected | ||||
| assertions: 1587 | 1418 passed | 148 failed | 21 failed as expected | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <testsuitesloose text artifact | ||||
| > | ||||
|   <testsuite name="<exe-name>" errors="17" failures="132" tests="1582" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> | ||||
|   <testsuite name="<exe-name>" errors="17" failures="132" tests="1588" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> | ||||
|     <properties> | ||||
|       <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/> | ||||
|       <property name="random-seed" value="1"/> | ||||
| @@ -254,6 +254,7 @@ Matchers.tests.cpp:<line number> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|     </testcase> | ||||
|     <testcase classname="<exe-name>.global" name="Copy and then generate a range" time="{duration}"/> | ||||
|     <testcase classname="<exe-name>.global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}"> | ||||
|       <error message="throwCustom()" type="REQUIRE_NOTHROW"> | ||||
| custom exception - not std | ||||
|   | ||||
| @@ -2816,6 +2816,57 @@ Nor would this | ||||
|       </Expression> | ||||
|       <OverallResult success="false"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="Copy and then generate a range" tags="[generators]" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" > | ||||
|         <Original> | ||||
|           elem % 2 == 1 | ||||
|         </Original> | ||||
|         <Expanded> | ||||
|           1 == 1 | ||||
|         </Expanded> | ||||
|       </Expression> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="Custom exceptions can be translated when testing for nothrow" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" > | ||||
|       <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" > | ||||
|         <Original> | ||||
| @@ -14872,7 +14923,7 @@ loose text artifact | ||||
|       </Section> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <OverallResults successes="1412" failures="149" expectedFailures="21"/> | ||||
|     <OverallResults successes="1418" failures="149" expectedFailures="21"/> | ||||
|   </Group> | ||||
|   <OverallResults successes="1412" failures="148" expectedFailures="21"/> | ||||
|   <OverallResults successes="1418" failures="148" expectedFailures="21"/> | ||||
| </Catch> | ||||
|   | ||||
| @@ -212,3 +212,28 @@ TEST_CASE("Nested generators and captured variables", "[generators]") { | ||||
|     auto values = GENERATE_COPY(range(from, to)); | ||||
|     REQUIRE(values > -6); | ||||
| } | ||||
|  | ||||
| namespace { | ||||
|     std::vector<int> make_data() { | ||||
|         return { 1, 3, 5, 7, 9, 11 }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #if defined(__clang__) | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wexit-time-destructors" | ||||
| #endif | ||||
|  | ||||
| TEST_CASE("Copy and then generate a range", "[generators]") { | ||||
|     static auto data = make_data(); | ||||
|  | ||||
|     // It is important to notice that a generator is only initialized | ||||
|     // **once** per run. What this means is that modifying data will not | ||||
|     // modify the underlying generator. | ||||
|     auto elem = GENERATE_REF(from_range(data.begin(), data.end())); | ||||
|     REQUIRE(elem % 2 == 1); | ||||
| } | ||||
|  | ||||
| #if defined(__clang__) | ||||
| #pragma clang diagnostic pop | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský