Compare commits

..

1 Commits

Author SHA1 Message Date
Martin Hořeňovský
fecf606a05 Add option to skip forward to the generator interface 2025-10-06 11:47:38 +02:00
24 changed files with 410 additions and 75 deletions

View File

@@ -252,9 +252,23 @@ struct IGenerator : GeneratorUntypedBase {
// Returns user-friendly string showing the current generator element
// Does not have to be overridden, IGenerator provides default implementation
virtual std::string stringifyImpl() const;
/**
* Customization point for `skipToNthElement`
*
* Does not have to be overridden, there is a default implementation.
* Can be overridden for better performance.
*
* If there are not enough elements, shall throw an error.
*
* Going backwards is not supported.
*/
virtual void skipToNthElementImpl( std::size_t n );
};
```
> `skipToNthElementImpl` was added in Catch2 vX.Y.Z
However, to be able to use your custom generator inside `GENERATE`, it
will need to be wrapped inside a `GeneratorWrapper<T>`.
`GeneratorWrapper<T>` is a value wrapper around a

View File

@@ -39,6 +39,22 @@ public:
current_number = m_dist(m_rand);
return true;
}
// Note: this improves the performance only a bit, but it is here
// to show how you can override the skip functionality.
void skipToNthElementImpl( std::size_t n ) override {
auto current_index = currentElementIndex();
assert(current_index <= n);
// We cannot jump forward the underlying generator directly,
// because we do not know how many bits each distributed number
// would consume to be generated.
for (; current_index < n; ++current_index) {
(void)m_dist(m_rand);
}
// We do not have to touch the current element index; it is handled
// by the base class.
}
};
// Avoids -Wweak-vtables

View File

@@ -57,36 +57,6 @@ namespace Detail {
}
} // end unnamed namespace
std::size_t catch_strnlen( const char* str, std::size_t n ) {
auto ret = std::char_traits<char>::find( str, n, '\0' );
if ( ret != nullptr ) { return static_cast<std::size_t>( ret - str ); }
return n;
}
std::string formatTimeT(std::time_t time) {
#ifdef _MSC_VER
std::tm timeInfo = {};
const auto err = gmtime_s( &timeInfo, &time );
if ( err ) {
return "gmtime from provided timepoint has failed. This "
"happens e.g. with pre-1970 dates using Microsoft libc";
}
#else
std::tm* timeInfo = std::gmtime( &time );
#endif
auto const timeStampSize = sizeof( "2017-01-16T17:06:45Z" );
char timeStamp[timeStampSize];
const char* const fmt = "%Y-%m-%dT%H:%M:%SZ";
#ifdef _MSC_VER
std::strftime( timeStamp, timeStampSize, fmt, &timeInfo );
#else
std::strftime( timeStamp, timeStampSize, fmt, timeInfo );
#endif
return std::string( timeStamp, timeStampSize - 1 );
}
std::string convertIntoString(StringRef string, bool escapeInvisibles) {
std::string ret;
// This is enough for the "don't escape invisibles" case, and a good

View File

@@ -8,7 +8,7 @@
#ifndef CATCH_TOSTRING_HPP_INCLUDED
#define CATCH_TOSTRING_HPP_INCLUDED
#include <ctime>
#include <vector>
#include <cstddef>
#include <type_traits>
@@ -40,9 +40,13 @@ namespace Catch {
namespace Detail {
std::size_t catch_strnlen(const char *str, std::size_t n);
std::string formatTimeT( std::time_t time );
inline std::size_t catch_strnlen(const char *str, std::size_t n) {
auto ret = std::char_traits<char>::find(str, n, '\0');
if (ret != nullptr) {
return static_cast<std::size_t>(ret - str);
}
return n;
}
constexpr StringRef unprintableString = "{?}"_sr;
@@ -407,38 +411,44 @@ namespace Catch {
// Separate std::tuple specialization
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
# include <tuple>
# include <utility>
#include <tuple>
namespace Catch {
namespace Detail {
template <typename Tuple, std::size_t... Is>
void PrintTuple( const Tuple& tuple,
std::ostream& os,
std::index_sequence<Is...> ) {
// 1 + Account for when the tuple is empty
char a[1 + sizeof...( Is )] = {
( ( os << ( Is ? ", " : " " )
<< ::Catch::Detail::stringify( std::get<Is>( tuple ) ) ),
'\0' )... };
(void)a;
}
template<
typename Tuple,
std::size_t N = 0,
bool = (N < std::tuple_size<Tuple>::value)
>
struct TupleElementPrinter {
static void print(const Tuple& tuple, std::ostream& os) {
os << (N ? ", " : " ")
<< ::Catch::Detail::stringify(std::get<N>(tuple));
TupleElementPrinter<Tuple, N + 1>::print(tuple, os);
}
};
} // namespace Detail
template<
typename Tuple,
std::size_t N
>
struct TupleElementPrinter<Tuple, N, false> {
static void print(const Tuple&, std::ostream&) {}
};
template <typename... Types>
}
template<typename ...Types>
struct StringMaker<std::tuple<Types...>> {
static std::string convert( const std::tuple<Types...>& tuple ) {
static std::string convert(const std::tuple<Types...>& tuple) {
ReusableStringStream rss;
rss << '{';
Detail::PrintTuple(
tuple,
rss.get(),
std::make_index_sequence<sizeof...( Types )>{} );
Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
rss << " }";
return rss.str();
}
};
} // namespace Catch
}
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
@@ -625,7 +635,28 @@ struct ratio_string<std::milli> {
const auto systemish = std::chrono::time_point_cast<
std::chrono::system_clock::duration>( time_point );
const auto as_time_t = std::chrono::system_clock::to_time_t( systemish );
return ::Catch::Detail::formatTimeT( as_time_t );
#ifdef _MSC_VER
std::tm timeInfo = {};
const auto err = gmtime_s( &timeInfo, &as_time_t );
if ( err ) {
return "gmtime from provided timepoint has failed. This "
"happens e.g. with pre-1970 dates using Microsoft libc";
}
#else
std::tm* timeInfo = std::gmtime( &as_time_t );
#endif
auto const timeStampSize = sizeof("2017-01-16T17:06:45Z");
char timeStamp[timeStampSize];
const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
#ifdef _MSC_VER
std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
#else
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
#endif
return std::string(timeStamp, timeStampSize - 1);
}
};
}

View File

@@ -7,6 +7,8 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <string>
namespace Catch {
@@ -21,6 +23,30 @@ namespace Catch {
return ret;
}
void GeneratorUntypedBase::skipToNthElementImpl( std::size_t n ) {
for ( size_t i = m_currentElementIndex; i < n; ++i ) {
bool isValid = next();
if ( !isValid ) {
Detail::throw_generator_exception(
"Coud not jump to Nth element: not enough elements" );
}
}
}
void GeneratorUntypedBase::skipToNthElement( std::size_t n ) {
if ( n < m_currentElementIndex ) {
Detail::throw_generator_exception(
"Tried to jump generator backwards" );
}
skipToNthElementImpl(n);
// Fixup tracking after moving the generator forward
// * Ensure that the correct element index is set after skipping
// * Invalidate cache
m_currentElementIndex = n;
m_stringReprCache.clear();
}
StringRef GeneratorUntypedBase::currentElementAsString() const {
if ( m_stringReprCache.empty() ) {
m_stringReprCache = stringifyImpl();

View File

@@ -35,6 +35,15 @@ namespace Catch {
//! Customization point for `currentElementAsString`
virtual std::string stringifyImpl() const = 0;
/**
* Customization point for skipping to the n-th element
*
* Defaults to successively calling `countedNext`. If there
* are not enough elements to reach the nth one, will throw
* an error.
*/
virtual void skipToNthElementImpl( std::size_t n );
public:
GeneratorUntypedBase() = default;
// Generation of copy ops is deprecated (and Clang will complain)
@@ -58,6 +67,13 @@ namespace Catch {
std::size_t currentElementIndex() const { return m_currentElementIndex; }
/**
* Moves the generator forward **to** the n-th element
*
* Cannot move backwards.
*/
void skipToNthElement( std::size_t n );
/**
* Returns generator's current element as user-friendly string.
*

View File

@@ -168,6 +168,7 @@ Nor would this
:test-result: PASS GENERATE can combine literals and generators
:test-result: PASS Generators -- adapters
:test-result: PASS Generators -- simple
:test-result: PASS Generators can be skipped forward
:test-result: PASS Generators internals
:test-result: PASS Greater-than inequalities with different epsilons
:test-result: PASS Hashers with different seed produce different hash with same test case

View File

@@ -166,6 +166,7 @@
:test-result: PASS GENERATE can combine literals and generators
:test-result: PASS Generators -- adapters
:test-result: PASS Generators -- simple
:test-result: PASS Generators can be skipped forward
:test-result: PASS Generators internals
:test-result: PASS Greater-than inequalities with different epsilons
:test-result: PASS Hashers with different seed produce different hash with same test case

View File

@@ -787,6 +787,13 @@ Generators.tests.cpp:<line number>: passed: j < i for: -1 < 3
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 1
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 2
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 0 for: 0 == 0
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.get() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 5 for: 5 == 5
GeneratorsImpl.tests.cpp:<line number>: passed: generator.get() == 5 for: 5 == 5
GeneratorsImpl.tests.cpp:<line number>: passed: generator.skipToNthElement( 3 )
GeneratorsImpl.tests.cpp:<line number>: passed: generator.skipToNthElement( 6 )
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 123 for: 123 == 123
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
@@ -2888,7 +2895,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected

View File

@@ -785,6 +785,13 @@ Generators.tests.cpp:<line number>: passed: j < i for: -1 < 3
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 1
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 2
Generators.tests.cpp:<line number>: passed: 4u * i > str.size() for: 12 > 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 0 for: 0 == 0
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.get() == 3 for: 3 == 3
GeneratorsImpl.tests.cpp:<line number>: passed: generator.currentElementIndex() == 5 for: 5 == 5
GeneratorsImpl.tests.cpp:<line number>: passed: generator.get() == 5 for: 5 == 5
GeneratorsImpl.tests.cpp:<line number>: passed: generator.skipToNthElement( 3 )
GeneratorsImpl.tests.cpp:<line number>: passed: generator.skipToNthElement( 6 )
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 123 for: 123 == 123
GeneratorsImpl.tests.cpp:<line number>: passed: !(gen.next()) for: !false
GeneratorsImpl.tests.cpp:<line number>: passed: gen.get() == 1 for: 1 == 1
@@ -2877,7 +2884,7 @@ InternalBenchmark.tests.cpp:<line number>: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:<line number>: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:<line number>: passed:
Misc.tests.cpp:<line number>: passed:
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected

View File

@@ -1719,6 +1719,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 435 | 335 passed | 76 failed | 7 skipped | 17 failed as expected
assertions: 2282 | 2105 passed | 136 failed | 41 failed as expected
test cases: 436 | 336 passed | 76 failed | 7 skipped | 17 failed as expected
assertions: 2289 | 2112 passed | 136 failed | 41 failed as expected

View File

@@ -5831,6 +5831,43 @@ Generators.tests.cpp:<line number>: PASSED:
with expansion:
12 > 3
-------------------------------------------------------------------------------
Generators can be skipped forward
-------------------------------------------------------------------------------
GeneratorsImpl.tests.cpp:<line number>
...............................................................................
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 0 )
with expansion:
0 == 0
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 3 )
with expansion:
3 == 3
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.get() == 3 )
with expansion:
3 == 3
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 5 )
with expansion:
5 == 5
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.get() == 5 )
with expansion:
5 == 5
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( generator.skipToNthElement( 3 ) )
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( generator.skipToNthElement( 6 ) )
-------------------------------------------------------------------------------
Generators internals
Single value
@@ -19295,6 +19332,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected

View File

@@ -5829,6 +5829,43 @@ Generators.tests.cpp:<line number>: PASSED:
with expansion:
12 > 3
-------------------------------------------------------------------------------
Generators can be skipped forward
-------------------------------------------------------------------------------
GeneratorsImpl.tests.cpp:<line number>
...............................................................................
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 0 )
with expansion:
0 == 0
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 3 )
with expansion:
3 == 3
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.get() == 3 )
with expansion:
3 == 3
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.currentElementIndex() == 5 )
with expansion:
5 == 5
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE( generator.get() == 5 )
with expansion:
5 == 5
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( generator.skipToNthElement( 3 ) )
GeneratorsImpl.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( generator.skipToNthElement( 6 ) )
-------------------------------------------------------------------------------
Generators internals
Single value
@@ -19284,6 +19321,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2315" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2322" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -837,6 +837,7 @@ at Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Generators -- simple" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators -- simple/one" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators -- simple/two" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators can be skipped forward" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals/Single value" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals/Preset values" time="{duration}" status="run"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2315" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2322" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -836,6 +836,7 @@ at Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Generators -- simple" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators -- simple/one" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators -- simple/two" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators can be skipped forward" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals/Single value" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Generators internals/Preset values" time="{duration}" status="run"/>

View File

@@ -144,6 +144,7 @@ at AssertionHandler.tests.cpp:<line number>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp">
<testCase name="Filter generator throws exception for empty generator" duration="{duration}"/>
<testCase name="Generators can be skipped forward" duration="{duration}"/>
<testCase name="Generators internals" duration="{duration}"/>
<testCase name="Generators internals/Single value" duration="{duration}"/>
<testCase name="Generators internals/Preset values" duration="{duration}"/>

View File

@@ -143,6 +143,7 @@ at AssertionHandler.tests.cpp:<line number>
</file>
<file path="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp">
<testCase name="Filter generator throws exception for empty generator" duration="{duration}"/>
<testCase name="Generators can be skipped forward" duration="{duration}"/>
<testCase name="Generators internals" duration="{duration}"/>
<testCase name="Generators internals/Single value" duration="{duration}"/>
<testCase name="Generators internals/Preset values" duration="{duration}"/>

View File

@@ -1430,6 +1430,20 @@ ok {test-number} - 4u * i > str.size() for: 12 > 1
ok {test-number} - 4u * i > str.size() for: 12 > 2
# Generators -- simple
ok {test-number} - 4u * i > str.size() for: 12 > 3
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 0 for: 0 == 0
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 3 for: 3 == 3
# Generators can be skipped forward
ok {test-number} - generator.get() == 3 for: 3 == 3
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 5 for: 5 == 5
# Generators can be skipped forward
ok {test-number} - generator.get() == 5 for: 5 == 5
# Generators can be skipped forward
ok {test-number} - generator.skipToNthElement( 3 )
# Generators can be skipped forward
ok {test-number} - generator.skipToNthElement( 6 )
# Generators internals
ok {test-number} - gen.get() == 123 for: 123 == 123
# Generators internals
@@ -4627,5 +4641,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2315
1..2322

View File

@@ -1428,6 +1428,20 @@ ok {test-number} - 4u * i > str.size() for: 12 > 1
ok {test-number} - 4u * i > str.size() for: 12 > 2
# Generators -- simple
ok {test-number} - 4u * i > str.size() for: 12 > 3
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 0 for: 0 == 0
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 3 for: 3 == 3
# Generators can be skipped forward
ok {test-number} - generator.get() == 3 for: 3 == 3
# Generators can be skipped forward
ok {test-number} - generator.currentElementIndex() == 5 for: 5 == 5
# Generators can be skipped forward
ok {test-number} - generator.get() == 5 for: 5 == 5
# Generators can be skipped forward
ok {test-number} - generator.skipToNthElement( 3 )
# Generators can be skipped forward
ok {test-number} - generator.skipToNthElement( 6 )
# Generators internals
ok {test-number} - gen.get() == 123 for: 123 == 123
# Generators internals
@@ -4616,5 +4630,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2315
1..2322

View File

@@ -414,6 +414,8 @@
##teamcity[testFinished name='Generators -- adapters' duration="{duration}"]
##teamcity[testStarted name='Generators -- simple']
##teamcity[testFinished name='Generators -- simple' duration="{duration}"]
##teamcity[testStarted name='Generators can be skipped forward']
##teamcity[testFinished name='Generators can be skipped forward' duration="{duration}"]
##teamcity[testStarted name='Generators internals']
##teamcity[testFinished name='Generators internals' duration="{duration}"]
##teamcity[testStarted name='Greater-than inequalities with different epsilons']

View File

@@ -414,6 +414,8 @@
##teamcity[testFinished name='Generators -- adapters' duration="{duration}"]
##teamcity[testStarted name='Generators -- simple']
##teamcity[testFinished name='Generators -- simple' duration="{duration}"]
##teamcity[testStarted name='Generators can be skipped forward']
##teamcity[testFinished name='Generators can be skipped forward' duration="{duration}"]
##teamcity[testStarted name='Generators internals']
##teamcity[testFinished name='Generators internals' duration="{duration}"]
##teamcity[testStarted name='Greater-than inequalities with different epsilons']

View File

@@ -6605,6 +6605,65 @@ Approx( 1.30000000000000004 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Generators can be skipped forward" tags="[generators]" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.get() == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.get() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.skipToNthElement( 3 )
</Original>
<Expanded>
generator.skipToNthElement( 3 )
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.skipToNthElement( 6 )
</Original>
<Expanded>
generator.skipToNthElement( 6 )
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Generators internals" tags="[generators][internals]" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Section name="Single value" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
@@ -22324,6 +22383,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2105" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="17" skips="6"/>
<OverallResults successes="2112" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="318" failures="95" expectedFailures="17" skips="6"/>
</Catch2TestRun>

View File

@@ -6605,6 +6605,65 @@ Approx( 1.30000000000000004 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Generators can be skipped forward" tags="[generators]" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 0
</Original>
<Expanded>
0 == 0
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.get() == 3
</Original>
<Expanded>
3 == 3
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.currentElementIndex() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.get() == 5
</Original>
<Expanded>
5 == 5
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.skipToNthElement( 3 )
</Original>
<Expanded>
generator.skipToNthElement( 3 )
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Original>
generator.skipToNthElement( 6 )
</Original>
<Expanded>
generator.skipToNthElement( 6 )
</Expanded>
</Expression>
<OverallResult success="true" skips="0"/>
</TestCase>
<TestCase name="Generators internals" tags="[generators][internals]" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Section name="Single value" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
@@ -22323,6 +22382,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2105" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="17" skips="6"/>
<OverallResults successes="2112" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="318" failures="95" expectedFailures="17" skips="6"/>
</Catch2TestRun>

View File

@@ -85,7 +85,7 @@ TEST_CASE("Generators internals", "[generators][internals]") {
filter([](int) { return false; }, values({ 1, 2, 3 })),
Catch::GeneratorException);
}
// Non-trivial usage
SECTION("Out-of-line predicates are copied into the generator") {
auto evilNumber = Catch::Detail::make_unique<int>(2);
@@ -586,3 +586,21 @@ TEST_CASE("from_range(container) supports ADL begin/end and arrays", "[generator
}
}
TEST_CASE( "Generators can be skipped forward", "[generators]" ) {
auto generator = Catch::Generators::FixedValuesGenerator<int>( { 0, 1, 2, 3, 4, 5 } );
REQUIRE( generator.currentElementIndex() == 0 );
generator.skipToNthElement( 3 );
REQUIRE( generator.currentElementIndex() == 3 );
REQUIRE( generator.get() == 3 );
generator.skipToNthElement( 5 );
REQUIRE( generator.currentElementIndex() == 5 );
REQUIRE( generator.get() == 5 );
// Backwards
REQUIRE_THROWS( generator.skipToNthElement( 3 ) );
// Past the end
REQUIRE_THROWS( generator.skipToNthElement( 6 ) );
}