From bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Sun, 29 Jun 2025 19:25:29 +0100 Subject: import catch2 3.8.1 --- .../SelfTest/IntrospectiveTests/ToString.tests.cpp | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 tests/SelfTest/IntrospectiveTests/ToString.tests.cpp (limited to 'tests/SelfTest/IntrospectiveTests/ToString.tests.cpp') diff --git a/tests/SelfTest/IntrospectiveTests/ToString.tests.cpp b/tests/SelfTest/IntrospectiveTests/ToString.tests.cpp new file mode 100644 index 0000000..e190460 --- /dev/null +++ b/tests/SelfTest/IntrospectiveTests/ToString.tests.cpp @@ -0,0 +1,120 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 + +#include +#include +#include +#include +#include + +#include + +enum class EnumClass3 { Value1, Value2, Value3, Value4 }; + +struct UsesSentinel { + using const_iterator = int const*; + using const_sentinel = std::nullptr_t; + + const_iterator begin() const { return nullptr; } + const_iterator end() const { return nullptr; } +}; + +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; + auto 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 **}" ); +} + +TEST_CASE("Range type with sentinel") { + CHECK( Catch::Detail::stringify(UsesSentinel{}) == "{ }" ); +} + +TEST_CASE("convertIntoString stringification helper", "[toString][approvals]") { + using namespace std::string_literals; + using Catch::Detail::convertIntoString; + using namespace Catch; + + SECTION("No escaping") { + CHECK(convertIntoString(""_sr, false) == R"("")"s); + CHECK(convertIntoString("abcd"_sr, false) == R"("abcd")"s); + CHECK(convertIntoString("ab\ncd"_sr, false) == "\"ab\ncd\""s); + CHECK(convertIntoString("ab\r\ncd"_sr, false) == "\"ab\r\ncd\""s); + CHECK(convertIntoString("ab\"cd"_sr, false) == R"("ab"cd")"s); + } + SECTION("Escaping invisibles") { + CHECK(convertIntoString(""_sr, true) == R"("")"s); + CHECK(convertIntoString("ab\ncd"_sr, true) == R"("ab\ncd")"s); + CHECK(convertIntoString("ab\r\ncd"_sr, true) == R"("ab\r\ncd")"s); + CHECK(convertIntoString("ab\tcd"_sr, true) == R"("ab\tcd")"s); + CHECK(convertIntoString("ab\fcd"_sr, true) == R"("ab\fcd")"s); + CHECK(convertIntoString("ab\"cd"_sr, true) == R"("ab"cd")"s); + } +} + +TEMPLATE_TEST_CASE( "Stringifying char arrays with statically known sizes", + "[toString]", + char, + signed char, + unsigned char ) { + using namespace std::string_literals; + TestType with_null_terminator[10] = "abc"; + CHECK( ::Catch::Detail::stringify( with_null_terminator ) == R"("abc")"s ); + + TestType no_null_terminator[3] = { 'a', 'b', 'c' }; + CHECK( ::Catch::Detail::stringify( no_null_terminator ) == R"("abc")"s ); +} + +TEST_CASE( "#2944 - Stringifying dates before 1970 should not crash", "[.approvals]" ) { + using Catch::Matchers::Equals; + using Days = std::chrono::duration>; + using SysDays = std::chrono::time_point; + Catch::StringMaker sm; + + // Check simple date first + const SysDays post1970{ Days{ 1 } }; + auto converted_post = sm.convert( post1970 ); + REQUIRE( converted_post == "1970-01-02T00:00:00Z" ); + + const SysDays pre1970{ Days{ -1 } }; + auto converted_pre = sm.convert( pre1970 ); + REQUIRE_THAT( + converted_pre, + Equals( "1969-12-31T00:00:00Z" ) || + Equals( "gmtime from provided timepoint has failed. This " + "happens e.g. with pre-1970 dates using Microsoft libc" ) ); +} -- cgit v1.2.3