diff options
| author | melak47 | 2018-09-20 13:13:35 +0100 |
|---|---|---|
| committer | Martin Hořeňovský | 2018-09-20 14:13:35 +0200 |
| commit | c638c5720970f03033755dd9ebb0e4e6dccb1289 (patch) | |
| tree | ca5f58bb48ed1f9d8f6383d544a42fcf8592aff6 /projects/SelfTest/UsageTests/ToStringVariant.tests.cpp | |
| parent | a575536abe20b58c48863600f8a71e93b4052b81 (diff) | |
| download | catch3-c638c5720970f03033755dd9ebb0e4e6dccb1289.tar.gz | |
Add StringMaker for std::variant, std::monostate (#1380)
The StringMaker is off by default and can be enabled by a new macro `CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER`, to avoid increasing the footprint of stringification machinery by default.
Diffstat (limited to 'projects/SelfTest/UsageTests/ToStringVariant.tests.cpp')
| -rw-r--r-- | projects/SelfTest/UsageTests/ToStringVariant.tests.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp b/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp new file mode 100644 index 00000000..62f923f0 --- /dev/null +++ b/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp @@ -0,0 +1,84 @@ +#define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER +#include "catch.hpp" + +#if defined(CATCH_CONFIG_CPP17_VARIANT) + +#include <string> +#include <variant> + +TEST_CASE( "variant<std::monostate>", "[toString][variant][approvals]") +{ + using type = std::variant<std::monostate>; + CHECK( "{ }" == ::Catch::Detail::stringify(type{}) ); + type value {}; + CHECK( "{ }" == ::Catch::Detail::stringify(value) ); + CHECK( "{ }" == ::Catch::Detail::stringify(std::get<0>(value)) ); +} + +TEST_CASE( "variant<int>", "[toString][variant][approvals]") +{ + using type = std::variant<int>; + CHECK( "0" == ::Catch::Detail::stringify(type{0}) ); +} + +TEST_CASE( "variant<float, int>", "[toString][variant][approvals]") +{ + using type = std::variant<float, int>; + CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) ); + CHECK( "0" == ::Catch::Detail::stringify(type{0}) ); + + SECTION("valueless by exception") { + struct sample { + operator int() const { throw 42; } + }; + + type value{1.5f}; + REQUIRE_THROWS_AS( value.emplace<int>(sample{}), int ); + REQUIRE( value.valueless_by_exception() ); + CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) ); + } +} + +TEST_CASE( "variant<string, int>", "[toString][variant][approvals]") +{ + using type = std::variant<std::string, int>; + CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) ); + CHECK( "0" == ::Catch::Detail::stringify(type{0}) ); +} + +TEST_CASE( "variant<variant<float, int>, string>", "[toString][variant][approvals]") +{ + using inner = std::variant<float, int>; + using type = std::variant<inner, std::string>; + CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) ); + CHECK( "0" == ::Catch::Detail::stringify(type{0}) ); + CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) ); + + struct sample { + operator int() const { throw 42; } + }; + + SECTION("valueless nested variant") { + type value = inner{0.5f}; + REQUIRE( std::holds_alternative<inner>(value) ); + REQUIRE( std::holds_alternative<float>(std::get<inner>(value)) ); + + REQUIRE_THROWS_AS( std::get<0>(value).emplace<int>(sample{}), int ); + + // outer variant is still valid and contains inner + REQUIRE( std::holds_alternative<inner>(value) ); + // inner variant is valueless + REQUIRE( std::get<inner>(value).valueless_by_exception() ); + CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) ); + } +} + +TEST_CASE( "variant<nullptr,int,const char *>", "[toString][variant][approvals]" ) +{ + using type = std::variant<std::nullptr_t,int,const char *>; + CHECK( "nullptr" == ::Catch::Detail::stringify(type{nullptr}) ); + CHECK( "42" == ::Catch::Detail::stringify(type{42}) ); + CHECK( "\"Catch me\"" == ::Catch::Detail::stringify(type{"Catch me"}) ); +} + +#endif // CATCH_INTERNAL_CONFIG_CPP17_VARIANT |