1
0
mirror of https://github.com/catchorg/Catch2.git synced 2025-01-16 15:18:00 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Martin Hořeňovský
d1625f30b1
Pick release notes from v2.13.1 2020-09-07 14:34:36 +02:00
Dawid Kurek
8f44e09a72
Remove superfluous values
The `0`s were needed for the expansion of parameter pack for the sake of
expander. Now when we have `index++` it is no more needed.
2020-09-07 14:30:58 +02:00
Sean Middleditch
31d4831245
Support sentinel-based ranges in default stringify (#2004) 2020-09-07 14:23:47 +02:00
mattkurz
08fb5cbab2
Fix typo in generators docs 2020-09-07 13:02:38 +02:00
Gregory Bond
5ad1a4fe61
Issue 1992: Better c++17 std::byte detection
This fixed buld errors for ubuntu-16 + clang and similar situations
where C++17 is supported in the compiler but not the default
C++ standard library.
2020-09-07 13:01:51 +02:00
Karthik Nishanth
2c1c02f7e7
Update ParseAndAddCatchTests.cmake 2020-09-07 13:00:55 +02:00
Martin Jeřábek
8851e779cf console colour: fix unintended colouring of user's stderr on POSIX
At some places, the colour reset code is printed after a newline.
Since the default output buffering to console is line-based, the reset
code is not actually written out. If messages from user code are printed
to stderr (different stream, same console), they are printed before
the colour reset code, and thus they are coloured.

Explicitly flushing the stream after writing the colour escape code solves
this.
2020-09-07 11:53:45 +02:00
17 changed files with 81 additions and 23 deletions

View File

@ -60,7 +60,7 @@ The specific order of the `SECTION`s will be "one", "one", "two", "two",
"two", "one"...
The fact that `GENERATE` introduces a virtual `SECTION` can als obe used
The fact that `GENERATE` introduces a virtual `SECTION` can also be used
to make a generator replay only some `SECTION`s, without having to
explicitly add a `SECTION`. As an example, the code below reports 3
assertions, because the "first" section is run once, but the "second"

View File

@ -3,6 +3,7 @@
# Release notes
**Contents**<br>
[3.0.1](#301)<br>
[2.13.1](#2131)<br>
[2.13.0](#2130)<br>
[2.12.4](#2124)<br>
[2.12.3](#2123)<br>
@ -147,6 +148,17 @@ new design.
* `catch2-with-main` also links in the default main
## 2.13.1
### Improvements
* `ParseAndAddCatchTests` handles CMake v3.18.0 correctly (#1984)
* Improved autodetection of `std::byte` (#1992)
* Simplified implementation of templated test cases (#2007)
* This should have a tiny positive effect on its compilation throughput
### Fixes
* Automatic stringification of ranges handles sentinel ranges properly (#2004)
## 2.13.0

View File

@ -190,8 +190,8 @@ function(ParseAndAddCatchTests_ParseFile SourceFile TestTarget)
string(REPLACE "," "\\," Name ${Name})
# Work around CMake 3.18.0 change in `add_test()`, before the escaped quotes were neccessary,
# beginning with CMake 3.18.0 the escaped double quotes confuse the call
if(${CMAKE_VERSION} VERSION_LESS "3.18")
# only with CMake 3.18.0 the escaped double quotes confuse the call. This change is reverted in 3.18.1
if(NOT ${CMAKE_VERSION} VERSION_EQUAL "3.18")
set(CTestName "\"${CTestName}\"")
endif()
# Add the test and set its properties

View File

@ -311,8 +311,8 @@ namespace Catch {
#endif
namespace Detail {
template<typename InputIterator>
std::string rangeToString(InputIterator first, InputIterator last) {
template<typename InputIterator, typename Sentinel = InputIterator>
std::string rangeToString(InputIterator first, Sentinel last) {
ReusableStringStream rss;
rss << "{ ";
if (first != last) {

View File

@ -240,7 +240,10 @@
// Check if byte is available and usable
# if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
# include <cstddef>
# if __cpp_lib_byte > 0
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
# endif
# endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
// Check if variant is available and usable

View File

@ -157,8 +157,10 @@ namespace {
private:
void setColour( const char* _escapeCode ) {
// The escape sequence must be flushed to console, otherwise if
// stdin and stderr are intermixed, we'd get accidentally coloured output.
getCurrentContext().getConfig()->stream()
<< '\033' << _escapeCode;
<< '\033' << _escapeCode << std::flush;
}
};

View File

@ -84,7 +84,7 @@
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
(void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
(void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@ -131,7 +131,7 @@
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
@ -176,7 +176,7 @@
void reg_tests() { \
int index = 0; \
using expander = int[]; \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
} \
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
@ -212,7 +212,7 @@
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
(void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
(void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@ -262,7 +262,7 @@
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@ -310,7 +310,7 @@
void reg_tests(){\
int index = 0;\
using expander = int[];\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\

View File

@ -180,6 +180,7 @@ Nor would this
:test-result: PASS Product with differing arities - std::tuple<int, double, float>
:test-result: PASS Product with differing arities - std::tuple<int, double>
:test-result: PASS Product with differing arities - std::tuple<int>
:test-result: PASS Range type with sentinel
:test-result: FAIL Reconstruction should be based on stringification: #914
:test-result: FAIL Regex string matcher
:test-result: PASS Regression test #1

View File

@ -1265,6 +1265,7 @@ CmdLine.tests.cpp:<line number>: passed: config.benchmarkWarmupTime == 10 for: 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 3 >= 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 2 >= 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 1 >= 1
ToString.tests.cpp:<line number>: passed: Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }"
Decomposition.tests.cpp:<line number>: failed: truthy(false) for: Hey, its truthy!
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("this STRING contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively

View File

@ -1380,6 +1380,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 349 | 275 passed | 70 failed | 4 failed as expected
assertions: 1989 | 1837 passed | 131 failed | 21 failed as expected
test cases: 350 | 276 passed | 70 failed | 4 failed as expected
assertions: 1990 | 1838 passed | 131 failed | 21 failed as expected

View File

@ -9326,6 +9326,17 @@ Misc.tests.cpp:<line number>: PASSED:
with expansion:
1 >= 1
-------------------------------------------------------------------------------
Range type with sentinel
-------------------------------------------------------------------------------
ToString.tests.cpp:<line number>
...............................................................................
ToString.tests.cpp:<line number>: PASSED:
CHECK( Catch::Detail::stringify(UsesSentinel{}) == "{ }" )
with expansion:
"{ }" == "{ }"
-------------------------------------------------------------------------------
Reconstruction should be based on stringification: #914
-------------------------------------------------------------------------------
@ -15654,6 +15665,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 349 | 259 passed | 86 failed | 4 failed as expected
assertions: 2006 | 1837 passed | 148 failed | 21 failed as expected
test cases: 350 | 260 passed | 86 failed | 4 failed as expected
assertions: 2007 | 1838 passed | 148 failed | 21 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="132" tests="2007" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="132" tests="2008" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/>
@ -1063,6 +1063,7 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double, float>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Range type with sentinel" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Reconstruction should be based on stringification: #914" time="{duration}" status="run">
<failure message="truthy(false)" type="CHECK">
FAILED:

View File

@ -187,6 +187,7 @@
</file>
<file path="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp">
<testCase name="Directly creating an EnumInfo" duration="{duration}"/>
<testCase name="Range type with sentinel" duration="{duration}"/>
<testCase name="parseEnums/No enums" duration="{duration}"/>
<testCase name="parseEnums/One enum value" duration="{duration}"/>
<testCase name="parseEnums/Multiple enum values" duration="{duration}"/>

View File

@ -2452,6 +2452,8 @@ ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 3 >= 1
ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 2 >= 1
# Product with differing arities - std::tuple<int>
ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 1 >= 1
# Range type with sentinel
ok {test-number} - Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }"
# Reconstruction should be based on stringification: #914
not ok {test-number} - truthy(false) for: Hey, its truthy!
# Regex string matcher
@ -4004,5 +4006,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..2006
1..2007

View File

@ -461,6 +461,8 @@ Message.tests.cpp:<line number>|nexplicit failure with message:|n "Message from
##teamcity[testFinished name='Product with differing arities - std::tuple<int, double>' duration="{duration}"]
##teamcity[testStarted name='Product with differing arities - std::tuple<int>']
##teamcity[testFinished name='Product with differing arities - std::tuple<int>' duration="{duration}"]
##teamcity[testStarted name='Range type with sentinel']
##teamcity[testFinished name='Range type with sentinel' duration="{duration}"]
##teamcity[testStarted name='Reconstruction should be based on stringification: #914']
Decomposition.tests.cpp:<line number>|nexpression failed|n CHECK( truthy(false) )|nwith expansion:|n Hey, its truthy!|n']
##teamcity[testFinished name='Reconstruction should be based on stringification: #914' duration="{duration}"]

View File

@ -11404,6 +11404,17 @@ Nor would this
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Range type with sentinel" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
<Original>
Catch::Detail::stringify(UsesSentinel{}) == "{ }"
</Original>
<Expanded>
"{ }" == "{ }"
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Reconstruction should be based on stringification: #914" tags="[.][Decomposition][failing]" filename="tests/<exe-name>/UsageTests/Decomposition.tests.cpp" >
<Expression success="false" type="CHECK" filename="tests/<exe-name>/UsageTests/Decomposition.tests.cpp" >
<Original>
@ -18568,9 +18579,9 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1837" failures="149" expectedFailures="21"/>
<OverallResultsCases successes="259" failures="86" expectedFailures="4"/>
<OverallResults successes="1838" failures="149" expectedFailures="21"/>
<OverallResultsCases successes="260" failures="86" expectedFailures="4"/>
</Group>
<OverallResults successes="1837" failures="148" expectedFailures="21"/>
<OverallResultsCases successes="259" failures="86" expectedFailures="4"/>
<OverallResults successes="1838" failures="148" expectedFailures="21"/>
<OverallResultsCases successes="260" failures="86" expectedFailures="4"/>
</Catch>

View File

@ -4,6 +4,13 @@
enum class EnumClass3 { Value1, Value2, Value3, Value4 };
struct UsesSentinel {
using const_iterator = int const*;
using const_sentinel = std::nullptr_t;
const_iterator begin() const { return nullptr; }
const_iterator end() const { return nullptr; }
};
TEST_CASE( "parseEnums", "[Strings][enums]" ) {
using namespace Catch::Matchers;
@ -40,3 +47,7 @@ TEST_CASE( "Directly creating an EnumInfo" ) {
CHECK( enumInfo->lookup(1) == "Value2" );
CHECK( enumInfo->lookup(3) == "{** unexpected enum value **}" );
}
TEST_CASE("Range type with sentinel") {
CHECK( Catch::Detail::stringify(UsesSentinel{}) == "{ }" );
}