Compare commits

..

3 Commits

Author SHA1 Message Date
ZXShady
33e6fd217a Remove recursion when stringifying std::tuple 2025-10-04 22:10:36 +02:00
ZXShady
a58df2d7c5 Outline part of formatting system_clock's time_point into cpp file 2025-10-04 22:10:36 +02:00
ZXShady
a9223b2bb3 Outline catch_strnlen's definition into catch_tostring.cpp 2025-10-04 22:10:36 +02:00
30 changed files with 122 additions and 618 deletions

View File

@@ -252,23 +252,9 @@ 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,22 +39,6 @@ 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,6 +57,36 @@ 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,13 +40,9 @@ namespace Catch {
namespace Detail {
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;
}
std::size_t catch_strnlen(const char *str, std::size_t n);
std::string formatTimeT( std::time_t time );
constexpr StringRef unprintableString = "{?}"_sr;
@@ -411,44 +407,38 @@ namespace Catch {
// Separate std::tuple specialization
#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)
#include <tuple>
# include <tuple>
# include <utility>
namespace Catch {
namespace Detail {
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);
}
};
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
>
struct TupleElementPrinter<Tuple, N, false> {
static void print(const Tuple&, std::ostream&) {}
};
} // namespace Detail
}
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::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());
Detail::PrintTuple(
tuple,
rss.get(),
std::make_index_sequence<sizeof...( Types )>{} );
rss << " }";
return rss.str();
}
};
}
} // namespace Catch
#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
@@ -635,28 +625,7 @@ 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 );
#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);
return ::Catch::Detail::formatTimeT( as_time_t );
}
};
}

View File

@@ -7,8 +7,6 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/interfaces/catch_interfaces_generatortracker.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <string>
namespace Catch {
@@ -23,30 +21,6 @@ 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,15 +35,6 @@ 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)
@@ -67,13 +58,6 @@ 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

@@ -129,8 +129,12 @@ namespace Catch {
for ( auto const& child : m_children ) {
if ( child->isSectionTracker() &&
static_cast<SectionTracker const&>( *child )
.trimmedName() == filters[0] ) {
std::find( filters.begin(),
filters.end(),
static_cast<SectionTracker const&>(
*child )
.trimmedName() ) !=
filters.end() ) {
return true;
}
}

View File

@@ -172,9 +172,9 @@ namespace TestCaseTracking {
bool SectionTracker::isComplete() const {
bool complete = true;
if ( m_filters.empty()
if (m_filters.empty()
|| m_filters[0].empty()
|| m_filters[0] == m_trimmed_name ) {
|| std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
complete = TrackerBase::isComplete();
}
return complete;

View File

@@ -310,23 +310,38 @@ set_tests_properties(UnmatchedOutputFilter
PASS_REGULAR_EXPRESSION "No test cases matched '\\[this-tag-does-not-exist\\]'"
)
add_test(NAME FilteredSections::SimpleExample::1 COMMAND $<TARGET_FILE:SelfTest> \#1394 -c RunSection)
set_tests_properties(FilteredSections::SimpleExample::1 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
add_test(NAME FilteredSections::SimpleExample::2 COMMAND $<TARGET_FILE:SelfTest> \#1394\ nested -c NestedRunSection -c s1)
set_tests_properties(FilteredSections::SimpleExample::2 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
add_test(NAME FilteredSection-1 COMMAND $<TARGET_FILE:SelfTest> \#1394 -c RunSection)
set_tests_properties(FilteredSection-1 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
add_test(NAME FilteredSection-2 COMMAND $<TARGET_FILE:SelfTest> \#1394\ nested -c NestedRunSection -c s1)
set_tests_properties(FilteredSection-2 PROPERTIES FAIL_REGULAR_EXPRESSION "No tests ran")
add_test(
NAME
FilteredSections::GeneratorsDontCauseInfiniteLoop
FilteredSection::GeneratorsDontCauseInfiniteLoop-1
COMMAND
$<TARGET_FILE:SelfTest> "#2025: original repro" -c "fov_0"
)
set_tests_properties(FilteredSections::GeneratorsDontCauseInfiniteLoop
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-1
PROPERTIES
PASS_REGULAR_EXPRESSION "inside with fov: 0" # This should happen
FAIL_REGULAR_EXPRESSION "inside with fov: 1" # This would mean there was no filtering
)
# GENERATE between filtered sections (both are selected)
add_test(
NAME
FilteredSection::GeneratorsDontCauseInfiniteLoop-2
COMMAND
$<TARGET_FILE:SelfTest> "#2025: same-level sections"
-c "A"
-c "B"
--colour-mode none
)
set_tests_properties(FilteredSection::GeneratorsDontCauseInfiniteLoop-2
PROPERTIES
PASS_REGULAR_EXPRESSION "All tests passed \\(4 assertions in 1 test case\\)"
)
add_test(NAME ApprovalTests
COMMAND
Python3::Interpreter
@@ -679,14 +694,6 @@ set_tests_properties("Bazel::RngSeedEnvVar::MalformedValueIsIgnored"
PASS_REGULAR_EXPRESSION "Randomness seeded to: 17171717"
)
add_test(NAME "FilteredSections::DifferentSimpleFilters"
COMMAND
Python3::Interpreter "${CMAKE_CURRENT_LIST_DIR}/TestScripts/testSectionFiltering.py" $<TARGET_FILE:SelfTest>
)
set_tests_properties("FilteredSections::DifferentSimpleFilters"
PROPERTIES
LABELS "uses-python"
)
list(APPEND CATCH_TEST_TARGETS SelfTest)
set(CATCH_TEST_TARGETS ${CATCH_TEST_TARGETS} PARENT_SCOPE)

View File

@@ -168,7 +168,6 @@ 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,7 +166,6 @@
: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,13 +787,6 @@ 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
@@ -2895,7 +2888,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: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected

View File

@@ -785,13 +785,6 @@ 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
@@ -2884,7 +2877,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: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 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: 436 | 336 passed | 76 failed | 7 skipped | 17 failed as expected
assertions: 2289 | 2112 passed | 136 failed | 41 failed as expected
test cases: 435 | 335 passed | 76 failed | 7 skipped | 17 failed as expected
assertions: 2282 | 2105 passed | 136 failed | 41 failed as expected

View File

@@ -5831,43 +5831,6 @@ 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
@@ -19332,6 +19295,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected

View File

@@ -5829,43 +5829,6 @@ 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
@@ -19321,6 +19284,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 436 | 318 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2310 | 2112 passed | 157 failed | 41 failed as expected
test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
assertions: 2303 | 2105 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="2322" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2315" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -837,7 +837,6 @@ 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="2322" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="140" skipped="12" tests="2315" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="random-seed" value="1"/>
<property name="filters" value="&quot;*&quot; ~[!nonportable] ~[!benchmark] ~[approvals]"/>
@@ -836,7 +836,6 @@ 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,7 +144,6 @@ 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,7 +143,6 @@ 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,20 +1430,6 @@ 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
@@ -4641,5 +4627,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2322
1..2315

View File

@@ -1428,20 +1428,6 @@ 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
@@ -4630,5 +4616,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2322
1..2315

View File

@@ -414,8 +414,6 @@
##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,8 +414,6 @@
##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,65 +6605,6 @@ 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" >
@@ -22383,6 +22324,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2112" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="318" failures="95" expectedFailures="17" skips="6"/>
<OverallResults successes="2105" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="17" skips="6"/>
</Catch2TestRun>

View File

@@ -6605,65 +6605,6 @@ 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" >
@@ -22382,6 +22323,6 @@ Approx( -1.95996398454005449 )
</Section>
<OverallResult success="true" skips="0"/>
</TestCase>
<OverallResults successes="2112" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="318" failures="95" expectedFailures="17" skips="6"/>
<OverallResults successes="2105" failures="157" expectedFailures="41" skips="12"/>
<OverallResultsCases successes="317" failures="95" expectedFailures="17" skips="6"/>
</Catch2TestRun>

View File

@@ -7,7 +7,6 @@
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_test_macros.hpp>
#include <catch2/generators/catch_generators.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_case_insensitive_comparisons.hpp>
#include <catch2/internal/catch_optional.hpp>
@@ -171,64 +170,3 @@ TEST_CASE( "Decomposer checks that the argument is 0 when handling "
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
}
TEST_CASE( "foo", "[approvals]" ) {
SECTION( "A" ) {
SECTION( "B1" ) { REQUIRE( true ); }
SECTION( "B2" ) { REQUIRE( true ); }
SECTION( "B3" ) { REQUIRE( true ); }
}
}
TEST_CASE( "bar", "[approvals]" ) {
REQUIRE( true );
SECTION( "A" ) {
SECTION( "B1" ) { REQUIRE( true ); }
SECTION( "B2" ) { REQUIRE( true ); }
SECTION( "B3" ) { REQUIRE( true ); }
}
REQUIRE( true );
}
TEST_CASE( "baz", "[approvals]" ) {
SECTION( "A" ) { REQUIRE( true ); }
auto _ = GENERATE( 1, 2, 3 );
(void)_;
SECTION( "B" ) { REQUIRE( true ); }
}
TEST_CASE( "qux", "[approvals]" ) {
REQUIRE( true );
SECTION( "A" ) { REQUIRE( true ); }
auto _ = GENERATE( 1, 2, 3 );
(void)_;
SECTION( "B" ) { REQUIRE( true ); }
REQUIRE( true );
}
TEST_CASE( "corge", "[approvals]" ) {
REQUIRE( true );
SECTION( "A" ) {
REQUIRE( true );
}
auto i = GENERATE( 1, 2, 3 );
DYNAMIC_SECTION( "i=" << i ) {
REQUIRE( true );
}
REQUIRE( true );
}
TEST_CASE("grault", "[approvals]") {
REQUIRE( true );
SECTION( "A" ) {
REQUIRE( true );
}
SECTION("B") {
auto i = GENERATE( 1, 2, 3 );
DYNAMIC_SECTION( "i=" << i ) {
REQUIRE( true );
}
}
REQUIRE( true );
}

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,21 +586,3 @@ 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 ) );
}

View File

@@ -354,9 +354,27 @@ TEST_CASE("#1514: stderr/stdout is not captured in tests aborted by an exception
FAIL("1514");
}
TEST_CASE( "#2025: -c shouldn't cause infinite loop", "[sections][generators][regression][.approvals]" ) {
SECTION( "Check cursor from buffer offset" ) {
auto bufPos = GENERATE_REF( range( 0, 44 ) );
WHEN( "Buffer position is " << bufPos ) { REQUIRE( 1 == 1 ); }
}
}
TEST_CASE("#2025: original repro", "[sections][generators][regression][.approvals]") {
auto fov = GENERATE(true, false);
DYNAMIC_SECTION("fov_" << fov) {
std::cout << "inside with fov: " << fov << '\n';
}
}
TEST_CASE("#2025: same-level sections", "[sections][generators][regression][.approvals]") {
SECTION("A") {
SUCCEED();
}
auto i = GENERATE(1, 2, 3);
SECTION("B") {
REQUIRE(i < 4);
}
}

View File

@@ -1,128 +0,0 @@
#!/usr/bin/env python3
# Copyright Catch2 Authors
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at
# https://www.boost.org/LICENSE_1_0.txt)
# SPDX-License-Identifier: BSL-1.0
"""
This test script verifies the behaviour of the legacy section filtering
using `-c`, `--section` CLI parameters.
This is done by having a hardcoded set of test filter + section filter
combinations, together with the expected number of assertions that will
be run inside the test for given filter combo.
"""
import os
import subprocess
import sys
from typing import Tuple, List
import xml.etree.ElementTree as ET
def make_cli_filter(section_names: Tuple[str, ...]) -> List[str]:
final = []
for name in section_names:
final.append('--section')
final.append(name)
return final
def run_one_test(binary_path: str, test_name: str, section_names: Tuple[str, ...], expected_assertions: int):
cmd = [
binary_path,
'--reporter', 'xml',
test_name
]
cmd.extend(make_cli_filter(section_names))
try:
ret = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
universal_newlines=True,
)
stdout = ret.stdout
except subprocess.SubprocessError as ex:
print('Could not run "{}"'.format(cmd))
print("Return code: {}".format(ex.returncode))
print("stdout: {}".format(ex.stdout))
print("stderr: {}".format(ex.stderr))
raise
try:
tree = ET.fromstring(stdout)
except ET.ParseError as ex:
print("Invalid XML: '{}'".format(ex))
raise
# Validate that we ran exactly 1 test case, and it passed
test_case_stats = tree.find('OverallResultsCases')
expected_testcases = {'successes' : '1', 'failures' : '0', 'expectedFailures': '0', 'skips': '0'}
assert test_case_stats.attrib == expected_testcases, f'We did not run single passing test case as expected. {test_name}: {test_case_stats.attrib}'
# Validate that we got exactly the expected number of passing assertions
expected_assertions = {'successes' : str(expected_assertions), 'failures' : '0', 'expectedFailures': '0', 'skips': '0'}
assertion_stats = tree.find('OverallResults')
assert assertion_stats.attrib == expected_assertions, f'"{test_name}": {assertion_stats.attrib} vs {expected_assertions}'
# Inputs taken from issue #3038
tests = {
'foo': (
((), 3),
(('A',), 3),
(('A', 'B'), 0),
(('A', 'B1'), 1),
(('A', 'B2'), 1),
(('A', 'B1', 'B2'), 1),
(('A', 'B2', 'XXXX'), 1),
),
'bar': (
((), 9),
(('A',), 9),
(('A', 'B1'), 3),
(('XXXX',), 2),
(('B1',), 2),
(('A', 'B1', 'B2'), 3),
),
'baz': (
((), 4),
(('A',), 1),
(('A', 'B'), 1),
(('A', 'XXXX'), 1),
(('B',), 3),
(('XXXX',), 0),
),
'qux': (
((), 12),
(('A',), 7),
(('B',), 9),
(('B', 'XXXX'), 9),
(('XXXX',), 6),
),
'corge': (
((), 12),
(('i=2',), 7),
(('i=3',), 7),
),
'grault': (
((), 12),
(('A',), 3),
(('B',), 9),
(('B', 'i=1'), 7),
(('B', 'XXXX'), 6),
),
}
if len(sys.argv) != 2:
print("Wrong number of arguments, expected just the path to Catch2 SelfTest binary")
exit(1)
bin_path = os.path.abspath(sys.argv[1])
for test_filter, specs in tests.items():
for section_path, expected_assertions in specs:
run_one_test(bin_path, test_filter, section_path, expected_assertions)