From af8b54ecd59f8174aaaa97682e3544f2820a0900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 16 May 2022 11:56:11 +0200 Subject: [PATCH] Generators now keep track of the index of current element This might become potentially useful in the future, when we want to provide the ability to forward jump generators, to be able to simply reproduce specific input to a test. I am not yet sure how it would work, but the basic idea is that it could be similar to the `-c` switch for selecting specific `SECTION` in a test case. --- src/catch2/generators/catch_generators.hpp | 2 +- .../catch_interfaces_generatortracker.hpp | 35 ++++++++++++++++--- src/catch2/internal/catch_run_context.cpp | 2 +- .../GeneratorsImpl.tests.cpp | 11 ++++++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/catch2/generators/catch_generators.hpp b/src/catch2/generators/catch_generators.hpp index acfdb7dc..24af63d6 100644 --- a/src/catch2/generators/catch_generators.hpp +++ b/src/catch2/generators/catch_generators.hpp @@ -64,7 +64,7 @@ namespace Detail { return m_generator->get(); } bool next() { - return m_generator->next(); + return m_generator->countedNext(); } }; diff --git a/src/catch2/interfaces/catch_interfaces_generatortracker.hpp b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp index fa475e28..2efc4a58 100644 --- a/src/catch2/interfaces/catch_interfaces_generatortracker.hpp +++ b/src/catch2/interfaces/catch_interfaces_generatortracker.hpp @@ -14,6 +14,17 @@ namespace Catch { namespace Generators { class GeneratorUntypedBase { + // Counts based on `next` returning true + std::size_t m_currentElementIndex = 0; + + /** + * Attempts to move the generator to the next element + * + * Returns true iff the move succeeded (and a valid element + * can be retrieved). + */ + virtual bool next() = 0; + public: GeneratorUntypedBase() = default; // Generation of copy ops is deprecated (and Clang will complain) @@ -23,11 +34,25 @@ namespace Catch { virtual ~GeneratorUntypedBase(); // = default; - // Attempts to move the generator to the next element - // - // Returns true iff the move succeeded (and a valid element - // can be retrieved). - virtual bool next() = 0; + /** + * Attempts to move the generator to the next element + * + * Serves as a non-virtual interface to `next`, so that the + * top level interface can provide sanity checking and shared + * features. + * + * As with `next`, returns true iff the move succeeded and + * the generator has new valid element to provide. + */ + bool countedNext() { + auto ret = next(); + if ( ret ) { + ++m_currentElementIndex; + } + return ret; + } + + std::size_t currentElementIndex() const { return m_currentElementIndex; } }; using GeneratorBasePtr = Catch::Detail::unique_ptr; diff --git a/src/catch2/internal/catch_run_context.cpp b/src/catch2/internal/catch_run_context.cpp index 872783c6..7da8f714 100644 --- a/src/catch2/internal/catch_run_context.cpp +++ b/src/catch2/internal/catch_run_context.cpp @@ -143,7 +143,7 @@ namespace Catch { // this generator is still waiting for any child to start. if ( should_wait_for_child || ( m_runState == CompletedSuccessfully && - m_generator->next() ) ) { + m_generator->countedNext() ) ) { m_children.clear(); m_runState = Executing; } diff --git a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp index 2aad184d..42d80741 100644 --- a/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp @@ -413,3 +413,14 @@ TEST_CASE("GENERATE decays arrays", "[generators][compilation][approvals]") { auto str = GENERATE("abc", "def", "gh"); STATIC_REQUIRE(std::is_same::value); } + +TEST_CASE("Generators count returned elements", "[generators][approvals]") { + auto generator = Catch::Generators::FixedValuesGenerator( { 1, 2, 3 } ); + REQUIRE( generator.currentElementIndex() == 0 ); + REQUIRE( generator.countedNext() ); + REQUIRE( generator.currentElementIndex() == 1 ); + REQUIRE( generator.countedNext() ); + REQUIRE( generator.currentElementIndex() == 2 ); + REQUIRE_FALSE( generator.countedNext() ); + REQUIRE( generator.currentElementIndex() == 2 ); +}