EnumToString.tests.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "catch.hpp"
  2. namespace {
  3. // Enum without user-provided stream operator
  4. enum Enum1 { Enum1Value0, Enum1Value1 };
  5. // Enum with user-provided stream operator
  6. enum Enum2 { Enum2Value0, Enum2Value1 };
  7. std::ostream& operator<<( std::ostream& os, Enum2 v ) {
  8. return os << "E2{" << static_cast<int>(v) << "}";
  9. }
  10. } // end anonymous namespace
  11. TEST_CASE( "toString(enum)", "[toString][enum]" ) {
  12. Enum1 e0 = Enum1Value0;
  13. CHECK( ::Catch::Detail::stringify(e0) == "0" );
  14. Enum1 e1 = Enum1Value1;
  15. CHECK( ::Catch::Detail::stringify(e1) == "1" );
  16. }
  17. TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
  18. Enum2 e0 = Enum2Value0;
  19. CHECK( ::Catch::Detail::stringify(e0) == "E2{0}" );
  20. Enum2 e1 = Enum2Value1;
  21. CHECK( ::Catch::Detail::stringify(e1) == "E2{1}" );
  22. }
  23. // Enum class without user-provided stream operator
  24. namespace {
  25. enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 };
  26. // Enum class with user-provided stream operator
  27. enum class EnumClass2 { EnumClass2Value0, EnumClass2Value1 };
  28. std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
  29. switch( static_cast<int>( e2 ) ) {
  30. case static_cast<int>( EnumClass2::EnumClass2Value0 ):
  31. return os << "E2/V0";
  32. case static_cast<int>( EnumClass2::EnumClass2Value1 ):
  33. return os << "E2/V1";
  34. default:
  35. return os << "Unknown enum value " << static_cast<int>( e2 );
  36. }
  37. }
  38. } // end anonymous namespace
  39. TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
  40. EnumClass1 e0 = EnumClass1::EnumClass1Value0;
  41. CHECK( ::Catch::Detail::stringify(e0) == "0" );
  42. EnumClass1 e1 = EnumClass1::EnumClass1Value1;
  43. CHECK( ::Catch::Detail::stringify(e1) == "1" );
  44. }
  45. TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" ) {
  46. EnumClass2 e0 = EnumClass2::EnumClass2Value0;
  47. CHECK( ::Catch::Detail::stringify(e0) == "E2/V0" );
  48. EnumClass2 e1 = EnumClass2::EnumClass2Value1;
  49. CHECK( ::Catch::Detail::stringify(e1) == "E2/V1" );
  50. auto e3 = static_cast<EnumClass2>(10);
  51. CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" );
  52. }
  53. enum class EnumClass3 { Value1, Value2, Value3, Value4 };
  54. CATCH_REGISTER_ENUM( EnumClass3, EnumClass3::Value1, EnumClass3::Value2, EnumClass3::Value3 )
  55. TEST_CASE( "Enums can quickly have stringification enabled using REGISTER_ENUM" ) {
  56. using Catch::Detail::stringify;
  57. REQUIRE( stringify( EnumClass3::Value1 ) == "Value1" );
  58. REQUIRE( stringify( EnumClass3::Value2 ) == "Value2" );
  59. REQUIRE( stringify( EnumClass3::Value3 ) == "Value3" );
  60. REQUIRE( stringify( EnumClass3::Value4 ) == "{** unexpected enum value **}" );
  61. EnumClass3 ec3 = EnumClass3 ::Value2;
  62. REQUIRE( stringify( ec3 ) == "Value2" );
  63. }
  64. namespace Bikeshed {
  65. enum class Colours { Red, Green, Blue };
  66. }
  67. // Important!: This macro must appear at top level scope - not inside a namespace
  68. // You can fully qualify the names, or use a using if you prefer
  69. CATCH_REGISTER_ENUM( Bikeshed::Colours,
  70. Bikeshed::Colours::Red,
  71. Bikeshed::Colours::Green,
  72. Bikeshed::Colours::Blue )
  73. TEST_CASE( "Enums in namespaces can quickly have stringification enabled using REGISTER_ENUM" ) {
  74. using Catch::Detail::stringify;
  75. REQUIRE( stringify( Bikeshed::Colours::Red ) == "Red" );
  76. REQUIRE( stringify( Bikeshed::Colours::Blue ) == "Blue" );
  77. }