From 32eb90b9bdaf45bb1d76ca8bc4efaa3aeaf9a134 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 4 Jan 2018 10:21:52 +0000 Subject: [PATCH] Fix stringifying of unknown enums --- include/internal/catch_tostring.h | 34 +++++++++------ .../Baselines/compact.sw.approved.txt | 9 ++-- .../Baselines/console.std.approved.txt | 20 +-------- .../Baselines/console.sw.approved.txt | 38 +++++++++++++--- .../SelfTest/Baselines/junit.sw.approved.txt | 12 ++---- .../SelfTest/Baselines/xml.sw.approved.txt | 43 +++++++++++++++---- .../UsageTests/EnumToString.tests.cpp | 4 +- 7 files changed, 101 insertions(+), 59 deletions(-) diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index 2e7091ad..5ca019fc 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -57,25 +57,38 @@ namespace Catch { static const bool value = decltype(test(0))::value; }; + template + std::string convertUnknownEnumToString( E e ); + + template + typename std::enable_if::value, std::string>::type convertUnstreamable( T const& ) { + return Detail::unprintableString; + }; + template + typename std::enable_if::value, std::string>::type convertUnstreamable( T const& value ) { + return convertUnknownEnumToString( value ); + }; + } // namespace Detail + // If we decide for C++14, change these to enable_if_ts template struct StringMaker { template static typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type - convert(const Fake& t) { + convert(const Fake& value) { ReusableStringStream rss; - rss << t; + rss << value; return rss.str(); } template static typename std::enable_if::value, std::string>::type - convert(const Fake&) { - return Detail::unprintableString; + convert( const Fake& value ) { + return Detail::convertUnstreamable( value ); } }; @@ -88,8 +101,12 @@ namespace Catch { return ::Catch::StringMaker::type>::type>::convert(e); } - } // namespace Detail + template + std::string convertUnknownEnumToString( E e ) { + return ::Catch::Detail::stringify(static_cast::type>(e)); + } + } // namespace Detail // Some predefined specializations @@ -233,13 +250,6 @@ namespace Catch { } } - template - struct EnumStringMaker { - static std::string convert(const T& t) { - return ::Catch::Detail::stringify(static_cast::type>(t)); - } - }; - #ifdef __OBJC__ template<> struct StringMaker { diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt index b2c492cb..2c9b0b80 100644 --- a/projects/SelfTest/Baselines/compact.sw.approved.txt +++ b/projects/SelfTest/Baselines/compact.sw.approved.txt @@ -987,8 +987,8 @@ EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e1) == EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e3) == "Unknown enum value 10" for: "Unknown enum value 10" == "Unknown enum value 10" -EnumToString.tests.cpp:: failed: ::Catch::Detail::stringify(e0) == "0" for: "{?}" == "0" -EnumToString.tests.cpp:: failed: ::Catch::Detail::stringify(e1) == "1" for: "{?}" == "1" +EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e0) == "0" for: "0" == "0" +EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e1) == "1" for: "1" == "1" EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e0) == "E2{0}" for: "E2{0}" == "E2{0}" EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e1) == "E2{1}" for: "E2{1}" == "E2{1}" EnumToString.tests.cpp:: passed: ::Catch::Detail::stringify(e0) == "0" for: "0" == "0" @@ -1011,6 +1011,9 @@ ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(v) == ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(v) == "{ { /"hello/" }, { /"world/" } }" for: "{ { "hello" }, { "world" } }" == "{ { "hello" }, { "world" } }" +ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(bools) == "{ }" for: "{ }" == "{ }" +ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(bools) == "{ true }" for: "{ true }" == "{ true }" +ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(bools) == "{ true, false }" for: "{ true, false }" == "{ true, false }" ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(vv) == "{ }" for: "{ }" == "{ }" ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(vv) == "{ 42 }" for: "{ 42 }" == "{ 42 }" ToStringVector.tests.cpp:: passed: ::Catch::Detail::stringify(vv) == "{ 42, 250 }" for: "{ 42, 250 }" == "{ 42, 250 }" @@ -1041,5 +1044,5 @@ Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -Failed 50 test cases, failed 110 assertions. +Failed 49 test cases, failed 108 assertions. diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index 85b6fff3..9bb8e8c3 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -1063,23 +1063,7 @@ Tricky.tests.cpp:: FAILED: with expansion: "first" == "second" -------------------------------------------------------------------------------- -toString(enum class) -------------------------------------------------------------------------------- -EnumToString.tests.cpp: -............................................................................... - -EnumToString.tests.cpp:: FAILED: - CHECK( ::Catch::Detail::stringify(e0) == "0" ) -with expansion: - "{?}" == "0" - -EnumToString.tests.cpp:: FAILED: - CHECK( ::Catch::Detail::stringify(e1) == "1" ) -with expansion: - "{?}" == "1" - =============================================================================== -test cases: 193 | 141 passed | 48 failed | 4 failed as expected -assertions: 977 | 849 passed | 107 failed | 21 failed as expected +test cases: 194 | 143 passed | 47 failed | 4 failed as expected +assertions: 980 | 854 passed | 105 failed | 21 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 96fc922e..a457fa8d 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -7783,15 +7783,17 @@ toString(enum class) EnumToString.tests.cpp: ............................................................................... -EnumToString.tests.cpp:: FAILED: +EnumToString.tests.cpp:: +PASSED: CHECK( ::Catch::Detail::stringify(e0) == "0" ) with expansion: - "{?}" == "0" + "0" == "0" -EnumToString.tests.cpp:: FAILED: +EnumToString.tests.cpp:: +PASSED: CHECK( ::Catch::Detail::stringify(e1) == "1" ) with expansion: - "{?}" == "1" + "1" == "1" ------------------------------------------------------------------------------- toString(enum w/operator<<) @@ -7939,6 +7941,30 @@ with expansion: == "{ { "hello" }, { "world" } }" +------------------------------------------------------------------------------- +vector -> toString +------------------------------------------------------------------------------- +ToStringVector.tests.cpp: +............................................................................... + +ToStringVector.tests.cpp:: +PASSED: + REQUIRE( ::Catch::Detail::stringify(bools) == "{ }" ) +with expansion: + "{ }" == "{ }" + +ToStringVector.tests.cpp:: +PASSED: + REQUIRE( ::Catch::Detail::stringify(bools) == "{ true }" ) +with expansion: + "{ true }" == "{ true }" + +ToStringVector.tests.cpp:: +PASSED: + REQUIRE( ::Catch::Detail::stringify(bools) == "{ true, false }" ) +with expansion: + "{ true, false }" == "{ true, false }" + ------------------------------------------------------------------------------- vector -> toString ------------------------------------------------------------------------------- @@ -8196,6 +8222,6 @@ Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 193 | 139 passed | 50 failed | 4 failed as expected -assertions: 976 | 845 passed | 110 failed | 21 failed as expected +test cases: 194 | 141 passed | 49 failed | 4 failed as expected +assertions: 979 | 850 passed | 108 failed | 21 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index 435a40f0..58d76e46 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -824,14 +824,7 @@ Tricky.tests.cpp: - - -EnumToString.tests.cpp: - - -EnumToString.tests.cpp: - - + @@ -841,6 +834,7 @@ EnumToString.tests.cpp: + diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index b39b1b00..c3fc5265 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -8702,24 +8702,24 @@ loose text artifact - - + + ::Catch::Detail::stringify(e0) == "0" - "{?}" == "0" + "0" == "0" - + ::Catch::Detail::stringify(e1) == "1" - "{?}" == "1" + "1" == "1" - + @@ -8868,6 +8868,33 @@ loose text artifact + + + + ::Catch::Detail::stringify(bools) == "{ }" + + + "{ }" == "{ }" + + + + + ::Catch::Detail::stringify(bools) == "{ true }" + + + "{ true }" == "{ true }" + + + + + ::Catch::Detail::stringify(bools) == "{ true, false }" + + + "{ true, false }" == "{ true, false }" + + + + @@ -9114,7 +9141,7 @@ loose text artifact - + - + diff --git a/projects/SelfTest/UsageTests/EnumToString.tests.cpp b/projects/SelfTest/UsageTests/EnumToString.tests.cpp index be0da03a..7d18a292 100644 --- a/projects/SelfTest/UsageTests/EnumToString.tests.cpp +++ b/projects/SelfTest/UsageTests/EnumToString.tests.cpp @@ -28,9 +28,7 @@ TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) { // Enum class without user-provided stream operator enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 }; -// This fails, but has been hidden for a while - not sure if it's a regression or if it never worked -// - need to investigate -TEST_CASE( "toString(enum class)", "[toString][enum][enumClass][.]" ) { +TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) { EnumClass1 e0 = EnumClass1::EnumClass1Value0; CHECK( ::Catch::Detail::stringify(e0) == "0" ); EnumClass1 e1 = EnumClass1::EnumClass1Value1;