mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Merge branch enum stringification work
This commit is contained in:
		| @@ -6,6 +6,7 @@ | ||||
| [Catch::StringMaker specialisation](#catchstringmaker-specialisation)<br> | ||||
| [Catch::is_range specialisation](#catchis_range-specialisation)<br> | ||||
| [Exceptions](#exceptions)<br> | ||||
| [Enums](#enums)<br> | ||||
|  | ||||
| Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes). | ||||
| Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings. | ||||
| @@ -66,6 +67,44 @@ CATCH_TRANSLATE_EXCEPTION( MyType& ex ) { | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Enums | ||||
|  | ||||
| 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` specialiation for you with minimal code. | ||||
| Simply provide it the (qualified) enum name, followed by all the enum values, and you're done! | ||||
|  | ||||
| E.g. | ||||
|  | ||||
| ``` | ||||
| enum class Fruits { Banana, Apple, Mango }; | ||||
|  | ||||
| CATCH_REGISTER_ENUM( Fruits, Fruits::Banana, Fruits::Apple, Fruits::Mango ); | ||||
|  | ||||
| TEST_CASE() { | ||||
|     REQUIRE( Fruits::Mango == Fruits::Apple ); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ... or if the enum is in a namespace: | ||||
| ``` | ||||
| namespace Bikeshed { | ||||
|     enum class Colours { Red, Green, Blue }; | ||||
| } | ||||
|  | ||||
| // 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() { | ||||
|     REQUIRE( Bikeshed::Colours::Red == Bikeshed::Colours::Blue ); | ||||
| } | ||||
| ``` | ||||
|  | ||||
|  | ||||
| --- | ||||
|  | ||||
| [Home](Readme.md#top) | ||||
|   | ||||
							
								
								
									
										65
									
								
								include/internal/catch_enum_values_registry.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								include/internal/catch_enum_values_registry.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
|  *  Created by Phil on 4/4/2019. | ||||
|  *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved. | ||||
|  * | ||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| #include "catch_enum_values_registry.h" | ||||
| #include "catch_string_manip.h" | ||||
| #include "catch_stream.h" | ||||
|  | ||||
| #include <map> | ||||
| #include <cassert> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {} | ||||
|  | ||||
|     namespace Detail { | ||||
|  | ||||
|         std::vector<std::string> parseEnums( StringRef enums ) { | ||||
|             auto enumValues = splitStringRef( enums, ',' ); | ||||
|             std::vector<std::string> parsed; | ||||
|             parsed.reserve( enumValues.size() ); | ||||
|             for( auto const& enumValue : enumValues ) { | ||||
|                 auto identifiers = splitStringRef( enumValue, ':' ); | ||||
|                 parsed.push_back( Catch::trim( identifiers.back() ) ); | ||||
|             } | ||||
|             return parsed; | ||||
|         } | ||||
|  | ||||
|         EnumInfo::~EnumInfo() {} | ||||
|  | ||||
|         StringRef EnumInfo::lookup( int value ) const { | ||||
|             for( auto const& valueToName : m_values ) { | ||||
|                 if( valueToName.first == value ) | ||||
|                     return valueToName.second; | ||||
|             } | ||||
|             return "{** unexpected enum value **}"; | ||||
|         } | ||||
|  | ||||
|         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { | ||||
|             std::unique_ptr<EnumInfo> 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() ); | ||||
|             std::size_t i = 0; | ||||
|             for( auto value : values ) | ||||
|                 enumInfo->m_values.push_back({ value, valueNames[i++] }); | ||||
|  | ||||
|             return enumInfo; | ||||
|         } | ||||
|  | ||||
|         EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) { | ||||
|             auto enumInfo = makeEnumInfo( enumName, allValueNames, values ); | ||||
|             EnumInfo* raw = enumInfo.get(); | ||||
|             m_enumInfos.push_back( std::move( enumInfo ) ); | ||||
|             return *raw; | ||||
|         } | ||||
|  | ||||
|     } // Detail | ||||
| } // Catch | ||||
|  | ||||
							
								
								
									
										34
									
								
								include/internal/catch_enum_values_registry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/internal/catch_enum_values_registry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  *  Created by Phil on 4/4/2019. | ||||
|  *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved. | ||||
|  * | ||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_enum_values_registry.h" | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     namespace Detail { | ||||
|  | ||||
|         std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ); | ||||
|  | ||||
|         class EnumValuesRegistry : public IMutableEnumValuesRegistry { | ||||
|  | ||||
|             std::vector<std::unique_ptr<EnumInfo>> m_enumInfos; | ||||
|  | ||||
|             EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override; | ||||
|         }; | ||||
|  | ||||
|         std::vector<std::string> parseEnums( StringRef enums ); | ||||
|  | ||||
|     } // Detail | ||||
|  | ||||
| } // Catch | ||||
|  | ||||
| #endif //TWOBLUECUBES_CATCH_ENUMVALUESREGISTRY_H_INCLUDED | ||||
							
								
								
									
										45
									
								
								include/internal/catch_interfaces_enum_values_registry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								include/internal/catch_interfaces_enum_values_registry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* | ||||
|  *  Created by Phil on 4/4/2019. | ||||
|  *  Copyright 2019 Two Blue Cubes Ltd. All rights reserved. | ||||
|  * | ||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED | ||||
|  | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     namespace Detail { | ||||
|         struct EnumInfo { | ||||
|             StringRef m_name; | ||||
|             std::vector<std::pair<int, std::string>> m_values; | ||||
|  | ||||
|             ~EnumInfo(); | ||||
|  | ||||
|             StringRef lookup( int value ) const; | ||||
|         }; | ||||
|     } // namespace Detail | ||||
|  | ||||
|     struct IMutableEnumValuesRegistry { | ||||
|         virtual ~IMutableEnumValuesRegistry(); | ||||
|  | ||||
|         virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0; | ||||
|  | ||||
|         template<typename E> | ||||
|         Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) { | ||||
|             std::vector<int> intValues; | ||||
|             intValues.reserve( values.size() ); | ||||
|             for( auto enumValue : values ) | ||||
|                 intValues.push_back( static_cast<int>( enumValue ) ); | ||||
|             return registerEnum( enumName, allEnums, intValues ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } // Catch | ||||
|  | ||||
| #endif //TWOBLUECUBES_CATCH_INTERFACESENUMVALUESREGISTRY_H_INCLUDED | ||||
| @@ -22,6 +22,8 @@ namespace Catch { | ||||
|     struct IReporterRegistry; | ||||
|     struct IReporterFactory; | ||||
|     struct ITagAliasRegistry; | ||||
|     struct IMutableEnumValuesRegistry; | ||||
|  | ||||
|     class StartupExceptionRegistry; | ||||
|  | ||||
|     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; | ||||
| @@ -32,7 +34,6 @@ namespace Catch { | ||||
|         virtual IReporterRegistry const& getReporterRegistry() const = 0; | ||||
|         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; | ||||
|         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; | ||||
|  | ||||
|         virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0; | ||||
|  | ||||
|  | ||||
| @@ -47,6 +48,7 @@ namespace Catch { | ||||
|         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; | ||||
|         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; | ||||
|         virtual void registerStartupException() noexcept = 0; | ||||
|         virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0; | ||||
|     }; | ||||
|  | ||||
|     IRegistryHub const& getRegistryHub(); | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include "catch_tag_alias_registry.h" | ||||
| #include "catch_startup_exception_registry.h" | ||||
| #include "catch_singletons.hpp" | ||||
| #include "catch_enum_values_registry.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -60,6 +61,9 @@ namespace Catch { | ||||
|             void registerStartupException() noexcept override { | ||||
|                 m_exceptionRegistry.add(std::current_exception()); | ||||
|             } | ||||
|             IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { | ||||
|                 return m_enumValuesRegistry; | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             TestRegistry m_testCaseRegistry; | ||||
| @@ -67,6 +71,7 @@ namespace Catch { | ||||
|             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; | ||||
|             TagAliasRegistry m_tagAliasRegistry; | ||||
|             StartupExceptionRegistry m_exceptionRegistry; | ||||
|             Detail::EnumValuesRegistry m_enumValuesRegistry; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -6,11 +6,13 @@ | ||||
|  */ | ||||
|  | ||||
| #include "catch_string_manip.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <algorithm> | ||||
| #include <ostream> | ||||
| #include <cstring> | ||||
| #include <cctype> | ||||
| #include <vector> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -65,6 +67,21 @@ namespace Catch { | ||||
|         return replaced; | ||||
|     } | ||||
|  | ||||
|     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) { | ||||
|         std::vector<StringRef> subStrings; | ||||
|         std::size_t start = 0; | ||||
|         for(std::size_t pos = 0; pos < str.size(); ++pos ) { | ||||
|             if( str[pos] == delimiter ) { | ||||
|                 if( pos - start > 1 ) | ||||
|                     subStrings.push_back( str.substr( start, pos-start ) ); | ||||
|                 start = pos+1; | ||||
|             } | ||||
|         } | ||||
|         if( start < str.size() ) | ||||
|             subStrings.push_back( str.substr( start, str.size()-start ) ); | ||||
|         return subStrings; | ||||
|     } | ||||
|  | ||||
|     pluralise::pluralise( std::size_t count, std::string const& label ) | ||||
|     :   m_count( count ), | ||||
|         m_label( label ) | ||||
|   | ||||
| @@ -7,8 +7,11 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_STRING_MANIP_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_STRING_MANIP_H_INCLUDED | ||||
|  | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <string> | ||||
| #include <iosfwd> | ||||
| #include <vector> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -20,6 +23,9 @@ namespace Catch { | ||||
|     void toLowerInPlace( std::string& s ); | ||||
|     std::string toLower( std::string const& s ); | ||||
|     std::string trim( std::string const& str ); | ||||
|  | ||||
|     // !!! Be aware, returns refs into original string - make sure original string outlives them | ||||
|     std::vector<StringRef> splitStringRef( StringRef str, char delimiter ); | ||||
|     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); | ||||
|  | ||||
|     struct pluralise { | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include <string> | ||||
| #include "catch_compiler_capabilities.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_interfaces_enum_values_registry.h" | ||||
|  | ||||
| #ifdef CATCH_CONFIG_CPP17_STRING_VIEW | ||||
| #include <string_view> | ||||
| @@ -639,6 +640,15 @@ struct ratio_string<std::milli> { | ||||
| } | ||||
| #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER | ||||
|  | ||||
| #define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \ | ||||
|     template<> struct Catch::StringMaker<enumName> { \ | ||||
|         static std::string convert( enumName value ) { \ | ||||
|             static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \ | ||||
|             return enumInfo.lookup( static_cast<int>( value ) ); \ | ||||
|         } \ | ||||
|     }; | ||||
|  | ||||
| #define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ ) | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning(pop) | ||||
|   | ||||
| @@ -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 | ||||
| @@ -97,6 +98,7 @@ set(INTERNAL_HEADERS | ||||
|         ${HEADER_DIR}/internal/catch_decomposer.h | ||||
|         ${HEADER_DIR}/internal/catch_default_main.hpp | ||||
|         ${HEADER_DIR}/internal/catch_enforce.h | ||||
|         ${HEADER_DIR}/internal/catch_enum_values_registry.h | ||||
|         ${HEADER_DIR}/internal/catch_errno_guard.h | ||||
|         ${HEADER_DIR}/internal/catch_exception_translator_registry.h | ||||
|         ${HEADER_DIR}/internal/catch_external_interfaces.h | ||||
| @@ -107,6 +109,7 @@ set(INTERNAL_HEADERS | ||||
|         ${HEADER_DIR}/internal/catch_impl.hpp | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_capture.h | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_config.h | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_enum_values_registry.h | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_exception.h | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h | ||||
|         ${HEADER_DIR}/internal/catch_interfaces_reporter.h | ||||
| @@ -182,6 +185,7 @@ set(IMPL_SOURCES | ||||
|         ${HEADER_DIR}/internal/catch_debugger.cpp | ||||
|         ${HEADER_DIR}/internal/catch_decomposer.cpp | ||||
|         ${HEADER_DIR}/internal/catch_enforce.cpp | ||||
|         ${HEADER_DIR}/internal/catch_enum_values_registry.cpp | ||||
|         ${HEADER_DIR}/internal/catch_errno_guard.cpp | ||||
|         ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp | ||||
|         ${HEADER_DIR}/internal/catch_fatal_condition.cpp | ||||
|   | ||||
| @@ -202,3 +202,15 @@ TEST_CASE( "replaceInPlace", "[Strings][StringManip]" ) { | ||||
|         CHECK( s == "didn|'t" ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| TEST_CASE( "splitString", "[Strings]" ) { | ||||
|     using namespace Catch::Matchers; | ||||
|     using Catch::splitStringRef; | ||||
|     using Catch::StringRef; | ||||
|  | ||||
|     CHECK_THAT( splitStringRef("", ',' ), Equals(std::vector<StringRef>() ) ); | ||||
|     CHECK_THAT( splitStringRef("abc", ',' ), Equals(std::vector<StringRef>{"abc"} ) ); | ||||
|     CHECK_THAT( splitStringRef("abc,def", ',' ), Equals(std::vector<StringRef>{"abc", "def"} ) ); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								projects/SelfTest/IntrospectiveTests/ToString.tests.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								projects/SelfTest/IntrospectiveTests/ToString.tests.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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<std::string>{} ) ); | ||||
|  | ||||
|     SECTION( "One enum value" ) { | ||||
|         CHECK_THAT( parseEnums( "ClassName::EnumName::Value1" ), | ||||
|                 Equals(std::vector<std::string>{"Value1"} ) ); | ||||
|         CHECK_THAT( parseEnums( "Value1" ), | ||||
|                 Equals( std::vector<std::string>{"Value1"} ) ); | ||||
|         CHECK_THAT( parseEnums( "EnumName::Value1" ), | ||||
|                 Equals(std::vector<std::string>{"Value1"} ) ); | ||||
|     } | ||||
|  | ||||
|     SECTION( "Multiple enum values" ) { | ||||
|         CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2" ), | ||||
|                     Equals( std::vector<std::string>{"Value1", "Value2"} ) ); | ||||
|         CHECK_THAT( parseEnums( "ClassName::EnumName::Value1, ClassName::EnumName::Value2, ClassName::EnumName::Value3" ), | ||||
|                     Equals( std::vector<std::string>{"Value1", "Value2", "Value3"} ) ); | ||||
|         CHECK_THAT( parseEnums( "ClassName::EnumName::Value1,ClassName::EnumName::Value2 , ClassName::EnumName::Value3" ), | ||||
|                     Equals( std::vector<std::string>{"Value1", "Value2", "Value3"} ) ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| TEST_CASE( "Directly creating an EnumInfo" ) { | ||||
|  | ||||
|     using namespace Catch::Detail; | ||||
|     std::unique_ptr<EnumInfo> 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 **}" ); | ||||
| } | ||||
| @@ -61,6 +61,39 @@ 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<EnumClass2>(10); | ||||
|     auto e3 = static_cast<EnumClass2>(10); | ||||
|     CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" ); | ||||
| } | ||||
|  | ||||
| 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" ) { | ||||
|     using Catch::Detail::stringify; | ||||
|     REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" ); | ||||
|     REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" ); | ||||
|     REQUIRE( stringify( EnumClass3::Value3 ) == "Value3" ); | ||||
|     REQUIRE( stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" ); | ||||
|  | ||||
|     EnumClass3 ec3 = EnumClass3 ::Value2; | ||||
|     REQUIRE( stringify( ec3 ) == "Value2" ); | ||||
| } | ||||
|  | ||||
| namespace Bikeshed { | ||||
|     enum class Colours { Red, Green, Blue }; | ||||
| } | ||||
|  | ||||
| // 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( "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" ); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil nash
					Phil nash