diff --git a/.clang-tidy b/.clang-tidy index 539010d9..3488457a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -34,7 +34,7 @@ Checks: >- -modernize-pass-by-value, performance-*, - -performance-enum-size, + performance-enum-size, portability-*, @@ -49,6 +49,7 @@ Checks: >- -readability-implicit-bool-conversion, -readability-isolate-declaration, -readability-magic-numbers, + -readability-math-missing-parentheses, #no, 'a + B * C' obeying math rules is not confusing, -readability-named-parameter, -readability-qualified-auto, -readability-redundant-access-specifiers, diff --git a/docs/tostring.md b/docs/tostring.md index b99b6742..513c1b44 100644 --- a/docs/tostring.md +++ b/docs/tostring.md @@ -75,7 +75,7 @@ CATCH_TRANSLATE_EXCEPTION( MyType const& ex ) { Enums that already have a `<<` overload for `std::ostream` will convert to strings as expected. If you only need to convert enums to strings for test reporting purposes you can provide a `StringMaker` specialisations as any other type. -However, as a convenience, Catch provides the `REGISTER_ENUM` helper macro that will generate the `StringMaker` specialisation for you with minimal code. +However, as a convenience, Catch provides the `CATCH_REGISTER_ENUM` helper macro that will generate the `StringMaker` specialisation for you with minimal code. Simply provide it the (qualified) enum name, followed by all the enum values, and you're done! E.g. diff --git a/extras/Catch.cmake b/extras/Catch.cmake index c1712885..cef73def 100644 --- a/extras/Catch.cmake +++ b/extras/Catch.cmake @@ -144,7 +144,7 @@ same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. ``CMAKE_CATCH_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not passed when calling ``catch_discover_tests``. This provides a mechanism for globally selecting a preferred test discovery behavior without having to modify each call site. - + ``SKIP_IS_FAILURE`` Disables skipped test detection. @@ -267,7 +267,6 @@ function(catch_discover_tests TARGET) " CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n" " TEST_DL_PATHS" " [==[" "${_DL_PATHS}" "]==]" "\n" " TEST_DL_FRAMEWORK_PATHS" " [==[" "${_DL_FRAMEWORK_PATHS}" "]==]" "\n" - " CTEST_FILE" " [==[" "${CTEST_FILE}" "]==]" "\n" " )" "\n" " endif()" "\n" " include(\"${ctest_tests_file}\")" "\n" diff --git a/src/catch2/catch_tostring.cpp b/src/catch2/catch_tostring.cpp index 3f034d1a..83327cfb 100644 --- a/src/catch2/catch_tostring.cpp +++ b/src/catch2/catch_tostring.cpp @@ -22,7 +22,10 @@ namespace Detail { const int hexThreshold = 255; struct Endianness { - enum Arch { Big, Little }; + enum Arch : uint8_t { + Big, + Little + }; static Arch which() { int one = 1; diff --git a/src/catch2/reporters/catch_reporter_console.cpp b/src/catch2/reporters/catch_reporter_console.cpp index c5678548..9529f39a 100644 --- a/src/catch2/reporters/catch_reporter_console.cpp +++ b/src/catch2/reporters/catch_reporter_console.cpp @@ -214,7 +214,7 @@ struct RowBreak {}; struct OutputFlush {}; class Duration { - enum class Unit { + enum class Unit : uint8_t { Auto, Nanoseconds, Microseconds, @@ -286,7 +286,10 @@ public: }; } // end anon namespace -enum class Justification { Left, Right }; +enum class Justification : uint8_t { + Left, + Right +}; struct ColumnInfo { std::string name; diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 08fbf09c..7be343a1 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -136,8 +136,8 @@ Nor would this :test-result: SKIP Empty generators can SKIP in constructor :test-result: PASS Empty stream name opens cout stream :test-result: FAIL EndsWith string matcher -:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM -:test-result: PASS Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +:test-result: PASS Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM +:test-result: PASS Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM :test-result: PASS Epsilon only applies to Approx's value :test-result: XFAIL Equality checks that should fail :test-result: PASS Equality checks that should succeed diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt index c4b7b967..0cd24e41 100644 --- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt @@ -134,8 +134,8 @@ :test-result: SKIP Empty generators can SKIP in constructor :test-result: PASS Empty stream name opens cout stream :test-result: FAIL EndsWith string matcher -:test-result: PASS Enums can quickly have stringification enabled using REGISTER_ENUM -:test-result: PASS Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +:test-result: PASS Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM +:test-result: PASS Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM :test-result: PASS Epsilon only applies to Approx's value :test-result: XFAIL Equality checks that should fail :test-result: PASS Equality checks that should succeed diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index d7e31e73..a53f40d1 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -4083,7 +4083,7 @@ with expansion: insensitive) ------------------------------------------------------------------------------- -Enums can quickly have stringification enabled using REGISTER_ENUM +Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ------------------------------------------------------------------------------- EnumToString.tests.cpp: ............................................................................... @@ -4117,7 +4117,7 @@ with expansion: ------------------------------------------------------------------------------- Enums in namespaces can quickly have stringification enabled using -REGISTER_ENUM +CATCH_REGISTER_ENUM ------------------------------------------------------------------------------- EnumToString.tests.cpp: ............................................................................... diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt index 2c1460af..418ccf7e 100644 --- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -4081,7 +4081,7 @@ with expansion: insensitive) ------------------------------------------------------------------------------- -Enums can quickly have stringification enabled using REGISTER_ENUM +Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ------------------------------------------------------------------------------- EnumToString.tests.cpp: ............................................................................... @@ -4115,7 +4115,7 @@ with expansion: ------------------------------------------------------------------------------- Enums in namespaces can quickly have stringification enabled using -REGISTER_ENUM +CATCH_REGISTER_ENUM ------------------------------------------------------------------------------- EnumToString.tests.cpp: ............................................................................... diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index 5c5407ad..c3571f3e 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -521,8 +521,8 @@ with expansion: at Matchers.tests.cpp: - - + + diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt index f44369e5..55f5520d 100644 --- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt @@ -520,8 +520,8 @@ with expansion: at Matchers.tests.cpp: - - + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index 9e26a142..af06793e 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -998,8 +998,8 @@ at Decomposition.tests.cpp: - - + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt index 7e6a7502..2d8d5105 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt @@ -997,8 +997,8 @@ at Decomposition.tests.cpp: - - + + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index 19b968b8..801946d3 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -1004,19 +1004,19 @@ ok {test-number} - Catch::makeStream( "" )->isConsole() for: true not ok {test-number} - testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring" # EndsWith string matcher not ok {test-number} - testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive) -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value1 ) == "Value1" for: "Value1" == "Value1" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value2 ) == "Value2" for: "Value2" == "Value2" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value3 ) == "Value3" for: "Value3" == "Value3" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" for: "{** unexpected enum value **}" == "{** unexpected enum value **}" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( ec3 ) == "Value2" for: "Value2" == "Value2" -# Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +# Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( Bikeshed::Colours::Red ) == "Red" for: "Red" == "Red" -# Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +# Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( Bikeshed::Colours::Blue ) == "Blue" for: "Blue" == "Blue" # Epsilon only applies to Approx's value ok {test-number} - 101.01 != Approx(100).epsilon(0.01) for: 101.01000000000000512 != Approx( 100.0 ) diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index d92b1276..7f281f64 100644 --- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -1002,19 +1002,19 @@ ok {test-number} - Catch::makeStream( "" )->isConsole() for: true not ok {test-number} - testStringForMatching(), EndsWith( "Substring" ) for: "this string contains 'abc' as a substring" ends with: "Substring" # EndsWith string matcher not ok {test-number} - testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) for: "this string contains 'abc' as a substring" ends with: "this" (case insensitive) -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value1 ) == "Value1" for: "Value1" == "Value1" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value2 ) == "Value2" for: "Value2" == "Value2" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value3 ) == "Value3" for: "Value3" == "Value3" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" for: "{** unexpected enum value **}" == "{** unexpected enum value **}" -# Enums can quickly have stringification enabled using REGISTER_ENUM +# Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( ec3 ) == "Value2" for: "Value2" == "Value2" -# Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +# Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( Bikeshed::Colours::Red ) == "Red" for: "Red" == "Red" -# Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM +# Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM ok {test-number} - stringify( Bikeshed::Colours::Blue ) == "Blue" for: "Blue" == "Blue" # Epsilon only applies to Approx's value ok {test-number} - 101.01 != Approx(100).epsilon(0.01) for: 101.01000000000000512 != Approx( 100.0 ) diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index 9a59fa6d..db485523 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -315,10 +315,10 @@ ##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:|n...............................................................................|n|nMatchers.tests.cpp:|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "Substring"|n'] ##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "this" (case insensitive)|n'] ##teamcity[testFinished name='EndsWith string matcher' duration="{duration}"] -##teamcity[testStarted name='Enums can quickly have stringification enabled using REGISTER_ENUM'] -##teamcity[testFinished name='Enums can quickly have stringification enabled using REGISTER_ENUM' duration="{duration}"] -##teamcity[testStarted name='Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM'] -##teamcity[testFinished name='Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM' duration="{duration}"] +##teamcity[testStarted name='Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM'] +##teamcity[testFinished name='Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM' duration="{duration}"] +##teamcity[testStarted name='Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM'] +##teamcity[testFinished name='Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM' duration="{duration}"] ##teamcity[testStarted name='Epsilon only applies to Approx|'s value'] ##teamcity[testFinished name='Epsilon only applies to Approx|'s value' duration="{duration}"] ##teamcity[testStarted name='Equality checks that should fail'] diff --git a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt index 989a37fe..dde8a682 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt @@ -315,10 +315,10 @@ ##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:|n...............................................................................|n|nMatchers.tests.cpp:|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "Substring" ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "Substring"|n'] ##teamcity[testFailed name='EndsWith string matcher' message='Matchers.tests.cpp:|nexpression failed|n CHECK_THAT( testStringForMatching(), EndsWith( "this", Catch::CaseSensitive::No ) )|nwith expansion:|n "this string contains |'abc|' as a substring" ends with: "this" (case insensitive)|n'] ##teamcity[testFinished name='EndsWith string matcher' duration="{duration}"] -##teamcity[testStarted name='Enums can quickly have stringification enabled using REGISTER_ENUM'] -##teamcity[testFinished name='Enums can quickly have stringification enabled using REGISTER_ENUM' duration="{duration}"] -##teamcity[testStarted name='Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM'] -##teamcity[testFinished name='Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM' duration="{duration}"] +##teamcity[testStarted name='Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM'] +##teamcity[testFinished name='Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM' duration="{duration}"] +##teamcity[testStarted name='Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM'] +##teamcity[testFinished name='Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM' duration="{duration}"] ##teamcity[testStarted name='Epsilon only applies to Approx|'s value'] ##teamcity[testFinished name='Epsilon only applies to Approx|'s value' duration="{duration}"] ##teamcity[testStarted name='Equality checks that should fail'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index 397eb487..aa6bd6a8 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -4493,7 +4493,7 @@ C - + stringify( EnumClass3::Value1 ) == "Value1" @@ -4538,7 +4538,7 @@ C - + stringify( Bikeshed::Colours::Red ) == "Red" diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index 56e3e8bf..7f3b4984 100644 --- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -4493,7 +4493,7 @@ C - + stringify( EnumClass3::Value1 ) == "Value1" @@ -4538,7 +4538,7 @@ C - + stringify( Bikeshed::Colours::Red ) == "Red" diff --git a/tests/SelfTest/UsageTests/Compilation.tests.cpp b/tests/SelfTest/UsageTests/Compilation.tests.cpp index a7fbf08f..7a6a1f25 100644 --- a/tests/SelfTest/UsageTests/Compilation.tests.cpp +++ b/tests/SelfTest/UsageTests/Compilation.tests.cpp @@ -8,6 +8,7 @@ #include +#include #include // Setup for #1403 -- look for global overloads of operator << for classes @@ -34,6 +35,7 @@ static std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) { /////////////////////////////// #include +#include #include #include @@ -467,3 +469,57 @@ TEST_CASE( "Comparing const std::weak_ordering instances must compile", REQUIRE( plain_ordering_1 == const_ordering_1 ); } #endif + +// Reproduce issue with yaml-cpp iterators, where the `const_iterator` +// for Node type has `const T` as the value_type. This is wrong for +// multitude of reasons, but there might be other libraries in the wild +// that share this issue, and the workaround needed to support +// `from_range(iter, iter)` helper with those libraries is easy enough. +class HasBadIterator { + std::array m_arr{}; + +public: + class iterator { + const int* m_ptr = nullptr; + + public: + iterator( const int* ptr ): m_ptr( ptr ) {} + + using difference_type = std::ptrdiff_t; + using value_type = const int; + using pointer = const int*; + using reference = const int&; + using iterator_category = std::input_iterator_tag; + + iterator& operator++() { + ++m_ptr; + return *this; + } + + iterator operator++( int ) { + auto ret( *this ); + ++( *this ); + return ret; + } + + friend bool operator==( iterator lhs, iterator rhs ) { + return lhs.m_ptr == rhs.m_ptr; + } + friend bool operator!=( iterator lhs, iterator rhs ) { + return !( lhs == rhs ); + } + + int operator*() const { return *m_ptr; } + }; + + iterator cbegin() const { return { m_arr.data() }; } + iterator cend() const { return { m_arr.data() + m_arr.size() }; } +}; + +TEST_CASE("from_range(iter, iter) supports const_iterators", "[generators][from-range][approvals]") { + using namespace Catch::Generators; + + HasBadIterator data; + auto gen = from_range(data.cbegin(), data.cend()); + (void)gen; +} diff --git a/tests/SelfTest/UsageTests/EnumToString.tests.cpp b/tests/SelfTest/UsageTests/EnumToString.tests.cpp index 362cf804..268a7cad 100644 --- a/tests/SelfTest/UsageTests/EnumToString.tests.cpp +++ b/tests/SelfTest/UsageTests/EnumToString.tests.cpp @@ -79,7 +79,7 @@ enum class EnumClass3 { Value1, Value2, Value3, Value4 }; CATCH_REGISTER_ENUM( EnumClass3, EnumClass3::Value1, EnumClass3::Value2, EnumClass3::Value3 ) -TEST_CASE( "Enums can quickly have stringification enabled using REGISTER_ENUM" ) { +TEST_CASE( "Enums can quickly have stringification enabled using CATCH_REGISTER_ENUM" ) { using Catch::Detail::stringify; REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" ); REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" ); @@ -101,7 +101,7 @@ CATCH_REGISTER_ENUM( Bikeshed::Colours, Bikeshed::Colours::Green, Bikeshed::Colours::Blue ) -TEST_CASE( "Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" ) { +TEST_CASE( "Enums in namespaces can quickly have stringification enabled using CATCH_REGISTER_ENUM" ) { using Catch::Detail::stringify; REQUIRE( stringify( Bikeshed::Colours::Red ) == "Red" ); REQUIRE( stringify( Bikeshed::Colours::Blue ) == "Blue" );