From f2ee4f17ad7040160eea73b326d431b4112ad25b Mon Sep 17 00:00:00 2001 From: Phil nash Date: Thu, 25 Apr 2019 10:13:11 +0100 Subject: [PATCH] Moved enum tests that depend on internals to IntrospectiveTests. - also factored out makeEnumInfo, so tests don't need to touch registry - and added usage test that involves namespace --- .../internal/catch_enum_values_registry.cpp | 8 ++- include/internal/catch_enum_values_registry.h | 4 +- projects/CMakeLists.txt | 1 + .../IntrospectiveTests/ToString.tests.cpp | 42 ++++++++++++++++ .../UsageTests/EnumToString.tests.cpp | 49 ++++++------------- 5 files changed, 67 insertions(+), 37 deletions(-) create mode 100644 projects/SelfTest/IntrospectiveTests/ToString.tests.cpp diff --git a/include/internal/catch_enum_values_registry.cpp b/include/internal/catch_enum_values_registry.cpp index 9204e047..a4dd6127 100644 --- a/include/internal/catch_enum_values_registry.cpp +++ b/include/internal/catch_enum_values_registry.cpp @@ -38,9 +38,10 @@ namespace Catch { return "{** unexpected enum value **}"; } - EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector const& values ) { + std::unique_ptr makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector const& values ) { std::unique_ptr enumInfo( new EnumInfo ); enumInfo->m_name = enumName; + enumInfo->m_values.reserve( values.size() ); const auto valueNames = Catch::Detail::parseEnums( allValueNames ); assert( valueNames.size() == values.size() ); @@ -48,6 +49,11 @@ namespace Catch { for( auto value : values ) enumInfo->m_values.push_back({ value, valueNames[i++] }); + return enumInfo; + } + + EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector const& values ) { + auto enumInfo = makeEnumInfo( enumName, allValueNames, values ); EnumInfo* raw = enumInfo.get(); m_enumInfos.push_back( std::move( enumInfo ) ); return *raw; diff --git a/include/internal/catch_enum_values_registry.h b/include/internal/catch_enum_values_registry.h index b6943ec2..985687bd 100644 --- a/include/internal/catch_enum_values_registry.h +++ b/include/internal/catch_enum_values_registry.h @@ -16,11 +16,13 @@ namespace Catch { namespace Detail { + std::unique_ptr makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector const& values ); + class EnumValuesRegistry : public IMutableEnumValuesRegistry { std::vector> m_enumInfos; - EnumInfo const& registerEnum(StringRef enumName, StringRef allEnums, std::vector const& values) override; + EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector const& values) override; }; std::vector parseEnums( StringRef enums ); diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 36263636..0d1c275d 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -22,6 +22,7 @@ set(TEST_SOURCES ${SELF_TEST_DIR}/IntrospectiveTests/Tag.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp + ${SELF_TEST_DIR}/IntrospectiveTests/ToString.tests.cpp ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp diff --git a/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp b/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp new file mode 100644 index 00000000..fc0e2a4f --- /dev/null +++ b/projects/SelfTest/IntrospectiveTests/ToString.tests.cpp @@ -0,0 +1,42 @@ +#include "catch.hpp" + +#include "internal/catch_enum_values_registry.h" + +enum class EnumClass3 { Value1, Value2, Value3, Value4 }; + + +TEST_CASE( "parseEnums", "[Strings][enums]" ) { + using namespace Catch::Matchers; + using Catch::Detail::parseEnums; + + SECTION( "No enums" ) + CHECK_THAT( parseEnums( "" ), Equals( std::vector{} ) ); + + SECTION( "One enum value" ) { + CHECK_THAT( parseEnums( "ClassName::EnumName::Value1" ), + Equals(std::vector{"Value1"} ) ); + CHECK_THAT( parseEnums( "Value1" ), + Equals( std::vector{"Value1"} ) ); + CHECK_THAT( parseEnums( "EnumName::Value1" ), + Equals(std::vector{"Value1"} ) ); + } + + SECTION( "Multiple enum values" ) { + CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), + Equals( std::vector{"Value1", "Value2"} ) ); + CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), + Equals( std::vector{"Value1", "Value2", "Value3"} ) ); + CHECK_THAT( parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), + Equals( std::vector{"Value1", "Value2", "Value3"} ) ); + } +} + +TEST_CASE( "Directly creating an EnumInfo" ) { + + using namespace Catch::Detail; + std::unique_ptr enumInfo = makeEnumInfo( "EnumName", "EnumName::Value1, EnumName::Value2", {0, 1} ); + + CHECK( enumInfo->lookup(0) == "Value1" ); + CHECK( enumInfo->lookup(1) == "Value2" ); + CHECK( enumInfo->lookup(3) == "{** unexpected enum value **}" ); +} diff --git a/projects/SelfTest/UsageTests/EnumToString.tests.cpp b/projects/SelfTest/UsageTests/EnumToString.tests.cpp index ee68968c..81ec5937 100644 --- a/projects/SelfTest/UsageTests/EnumToString.tests.cpp +++ b/projects/SelfTest/UsageTests/EnumToString.tests.cpp @@ -61,7 +61,7 @@ TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" ) EnumClass2 e1 = EnumClass2::EnumClass2Value1; CHECK( ::Catch::Detail::stringify(e1) == "E2/V1" ); - EnumClass2 e3 = static_cast(10); + auto e3 = static_cast(10); CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" ); } @@ -70,7 +70,7 @@ enum class EnumClass3 { Value1, Value2, Value3, Value4 }; CATCH_REGISTER_ENUM( EnumClass3, EnumClass3::Value1, EnumClass3::Value2, EnumClass3::Value3 ) -TEST_CASE( "REGISTER_ENUM" ) { +TEST_CASE( "Enums can quickly have stringification enabled using REGISTER_ENUM" ) { using Catch::Detail::stringify; REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" ); REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" ); @@ -81,40 +81,19 @@ TEST_CASE( "REGISTER_ENUM" ) { REQUIRE( stringify( ec3 ) == "Value2" ); } -#include "internal/catch_interfaces_enum_values_registry.h" - -TEST_CASE( "EnumInfo" ) { - - auto& hub = Catch::getMutableRegistryHub(); - auto& reg = hub.getMutableEnumValuesRegistry(); - auto const& enumInfo = reg.registerEnum( "EnumName", "EnumName::Value1, EnumName::Value2", {0, 1} ); - - CHECK( enumInfo.lookup(0) == "Value1" ); - CHECK( enumInfo.lookup(1) == "Value2" ); - CHECK( enumInfo.lookup(3) == "{** unexpected enum value **}" ); +namespace Bikeshed { + enum class Colours { Red, Green, Blue }; } -#include "internal/catch_enum_values_registry.h" +// Important!: This macro must appear at top level scope - not inside a namespace +// You can fully qualify the names, or use a using if you prefer +CATCH_REGISTER_ENUM( Bikeshed::Colours, + Bikeshed::Colours::Red, + Bikeshed::Colours::Green, + Bikeshed::Colours::Blue ); -TEST_CASE( "parseEnums", "[Strings][enums]" ) { - using namespace Catch::Matchers; - using Catch::Detail::parseEnums; - - SECTION( "No enums" ) - CHECK_THAT( parseEnums( "" ), Equals( std::vector{} ) ); - - SECTION( "One enum value" ) { - CHECK_THAT( parseEnums( "ClassName::EnumName::Value1" ), Equals(std::vector{"Value1"} ) ); - CHECK_THAT( parseEnums( "Value1" ), Equals( std::vector{"Value1"} ) ); - CHECK_THAT( parseEnums( "EnumName::Value1" ), Equals(std::vector{"Value1"} ) ); - } - - SECTION( "Multiple enum values" ) { - CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), - Equals( std::vector{"Value1", "Value2"} ) ); - CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), - Equals( std::vector{"Value1", "Value2", "Value3"} ) ); - CHECK_THAT( parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), - Equals( std::vector{"Value1", "Value2", "Value3"} ) ); - } +TEST_CASE( "Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" ) { + using Catch::Detail::stringify; + REQUIRE( stringify( Bikeshed::Colours::Red ) == "Red" ); + REQUIRE( stringify( Bikeshed::Colours::Blue ) == "Blue" ); }