diff --git a/iceoryx_hoofs/test/moduletests/test_utility_convert.cpp b/iceoryx_hoofs/test/moduletests/test_utility_convert.cpp index c2cd543ec5..0d17481ca4 100644 --- a/iceoryx_hoofs/test/moduletests/test_utility_convert.cpp +++ b/iceoryx_hoofs/test/moduletests/test_utility_convert.cpp @@ -21,8 +21,9 @@ #include "iox/std_string_support.hpp" #include "test.hpp" - +#include #include +#include namespace { using namespace ::testing; @@ -38,6 +39,15 @@ class convert_test : public Test void TearDown() override { } + template + std::string fp_to_string(T value) + { + static_assert(std::is_floating_point::value, "fp_to_string requires floating point type"); + + std::ostringstream oss; + oss << std::scientific << std::setprecision(std::numeric_limits::max_digits10) << value; + return oss.str(); + } }; @@ -303,60 +313,614 @@ TEST_F(convert_test, fromString_LongInt_Fail) ASSERT_THAT(result.has_value(), Eq(false)); } -TEST_F(convert_test, fromString_MinMaxShort) +TEST_F(convert_test, fromString_Integer_InvalidTrailingChar_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "6a70f10f-227b-4b0a-8149-e5ca3c793b5d"); + + using IntegerType = std::tuple; + std::vector invalid_input = {"42a", "74 ", "-52-"}; + + // a lambda to iterate all invalid_input cases converting to type decltype(dummy) + auto expect_failure = [&invalid_input](auto dummy) { + using T = decltype(dummy); + for (const auto& v : invalid_input) + { + auto invalid_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(invalid_ret.has_value(), Eq(false)); + } + }; + + std::apply([&expect_failure](auto... args) { (..., expect_failure(args)); }, IntegerType{}); +} + +/// SINGED INTEGRAL EDGE CASES START +/// inc: increment, dec: decrement + +TEST_F(convert_test, fromString_SignedChar_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "3a70481e-ae86-4b96-92c4-44169700e93a"); + + std::string source = "-128"; + auto signed_char_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(signed_char_min.has_value(), Eq(true)); + EXPECT_THAT(signed_char_min.value(), Eq(std::numeric_limits::min())); + + source = "127"; + auto signed_char_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(signed_char_max.has_value(), Eq(true)); + EXPECT_THAT(signed_char_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_SignedChar_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "23a3aa3d-954f-43f3-96e9-6b885bbb0c86"); + + std::string source = "-129"; + auto signed_char_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(signed_char_min_dec_1.has_value(), Eq(false)); + + source = "128"; + auto signed_char_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(signed_char_max_inc_1.has_value(), Eq(false)); +} + +TEST_F(convert_test, fromString_SignedShort_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "68f802ce-feb5-46d9-a956-dd3ca1a3ce53"); + + std::string source = "-32768"; + auto short_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(short_min.has_value(), Eq(true)); + EXPECT_THAT(short_min.value(), Eq(std::numeric_limits::min())); + + source = "32767"; + auto short_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(short_max.has_value(), Eq(true)); + EXPECT_THAT(short_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_SignedShort_EdgeCase_OutOfRange_Fail) { ::testing::Test::RecordProperty("TEST_ID", "98e33efd-ba39-4b88-8307-358be30e4e73"); - std::string source = "32767"; - auto gg = iox::convert::from_string(source.c_str()); - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); + + std::string source = "-32769"; + auto short_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(short_min_dec_1.has_value(), Eq(false)); + source = "32768"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); - source = "-32768"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); - source = "-32769"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); + auto short_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(short_max_inc_1.has_value(), Eq(false)); } -TEST_F(convert_test, fromString_MinMaxUNSIGNED_Short) +TEST_F(convert_test, fromString_SignedInt_EdgeCase_InRange_Success) { - ::testing::Test::RecordProperty("TEST_ID", "f9196939-ae5d-4c27-85bf-b3b084343261"); - std::string source = "65535"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); - source = "65536"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); - source = "0"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); - source = "-1"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); + ::testing::Test::RecordProperty("TEST_ID", "7333d0f9-dd48-4a88-85c9-2167d65633db"); + + std::string source = "-2147483648"; + auto int_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(int_min.has_value(), Eq(true)); + EXPECT_THAT(int_min.value(), Eq(std::numeric_limits::min())); + + source = "2147483647"; + auto int_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(int_max.has_value(), Eq(true)); + EXPECT_THAT(int_max.value(), Eq(std::numeric_limits::max())); } -TEST_F(convert_test, fromString_MinMaxInt) +TEST_F(convert_test, fromString_SignedInt_EdgeCase_OutOfRange_Fail) { ::testing::Test::RecordProperty("TEST_ID", "abf0fda5-044e-4f1b-bb1e-31b701578a3d"); - std::string source = "2147483647"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); + + std::string source = "-2147483649"; + auto int_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(int_min_dec_1.has_value(), Eq(false)); + source = "2147483648"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); - source = "-2147483648"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); - source = "-2147483649"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); + auto int_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(int_max_inc_1.has_value(), Eq(false)); +} + +// platform dependent (32/64 bit system only) +TEST_F(convert_test, fromString_SignedLong_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "5dc4c773-6a51-42b6-ad94-7ec885263856"); + + std::string source = std::to_string(std::numeric_limits::min()); + auto long_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_min.has_value(), Eq(true)); + EXPECT_THAT(long_min.value(), Eq(std::numeric_limits::min())); + + source = std::to_string(std::numeric_limits::max()); + auto long_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_max.has_value(), Eq(true)); + EXPECT_THAT(long_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_SignedLong_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "fb349f9c-0800-4f0b-8940-9012f9946b77"); + + constexpr bool IS_32_BIT{sizeof(long) != sizeof(long long)}; + + std::string source = IS_32_BIT ? "-2147483649" : "-9223372036854775809"; + auto long_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_min_dec_1.has_value(), Eq(false)); + + source = IS_32_BIT ? "2147483648" : "9223372036854775808"; + auto long_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_max_inc_1.has_value(), Eq(false)); +} + +TEST_F(convert_test, fromString_SignedLongLong_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "1f1b0456-3b50-49ce-a69d-fe1d71a39230"); + + std::string source = "-9223372036854775808"; + auto long_long_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_long_min.has_value(), Eq(true)); + // we don't use -9223372036854775808LL here for the compiler will parse it in way we don't want + EXPECT_THAT(long_long_min.value(), Eq(std::numeric_limits::min())); + + source = "9223372036854775807"; + auto long_long_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_long_max.has_value(), Eq(true)); + EXPECT_THAT(long_long_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_SignedLongLong_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "7c015ac0-06a7-407d-aa93-d39c50734951"); + + std::string source = "-9223372036854775809"; + auto long_long_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_long_min_dec_1.has_value(), Eq(false)); + + source = "9223372036854775808"; + auto long_long_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_long_max_inc_1.has_value(), Eq(false)); +} + +/// SINGED INTEGRAL EDGE CASES END + +/// UNSINGED INTEGRAL EDGE CASES START + +TEST_F(convert_test, fromString_UnSignedChar_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "4d2debf7-a6fb-40e1-b672-cb3520be98dd"); + + std::string source = "0"; + auto unchar_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unchar_min.has_value(), Eq(true)); + EXPECT_THAT(unchar_min.value(), Eq(0)); + + source = "255"; + auto unchar_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unchar_max.has_value(), Eq(true)); + EXPECT_THAT(unchar_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_UnSignedChar_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "c11d74a1-be55-41fc-952f-519546eb04fe"); + + std::string source = "-1"; + auto unchar_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unchar_min_dec_1.has_value(), Eq(false)); + + source = "256"; + auto unchar_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unchar_max_inc_1.has_value(), Eq(false)); } -TEST_F(convert_test, fromString_MinMaxUNSIGNED_Int) +TEST_F(convert_test, fromString_UnSignedShort_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "cf168594-e673-4dba-90b7-9b11a3edb967"); + + std::string source = "0"; + auto unshort_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unshort_min.has_value(), Eq(true)); + EXPECT_THAT(unshort_min.value(), Eq(0)); + + source = "65535"; + auto unshort_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unshort_max.has_value(), Eq(true)); + EXPECT_THAT(unshort_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_UnSignedShort_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "f9196939-ae5d-4c27-85bf-b3b084343261"); + + std::string source = "-1"; + auto unshort_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unshort_min_dec_1.has_value(), Eq(false)); + + source = "65536"; + auto unshort_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unshort_max_inc_1.has_value(), Eq(false)); +} + +TEST_F(convert_test, fromString_UnSignedInt_EdgeCase_InRange_Success) { ::testing::Test::RecordProperty("TEST_ID", "c2a832ef-3e86-4303-a98c-63c7b11ea789"); - std::string source = "4294967295"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); + + std::string source = "0"; + auto unint_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unint_min.has_value(), Eq(true)); + EXPECT_THAT(unint_min.value(), Eq(0)); + + source = "4294967295"; + auto unint_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unint_max.has_value(), Eq(true)); + EXPECT_THAT(unint_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_UnSignedInt_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "64216d84-c008-47fc-ab9b-0e8d77aeb6c2"); + + std::string source = "-1"; + auto unint_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unint_min_dec_1.has_value(), Eq(false)); + source = "4294967296"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); - source = "0"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(true)); - source = "-1"; - EXPECT_THAT(iox::convert::from_string(source.c_str()).has_value(), Eq(false)); + auto unint_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unint_max_inc_1.has_value(), Eq(false)); +} + +// platform dependent (32/64 bit system only) +TEST_F(convert_test, fromString_UnSignedLong_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "1aaac1ae-3d59-4443-8d88-bfe4e50569a8"); + + std::string source = "0"; + auto unlong_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_min.has_value(), Eq(true)); + EXPECT_THAT(unlong_min.value(), Eq(0)); + + source = std::to_string(std::numeric_limits::max()); + auto unlong_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_max.has_value(), Eq(true)); + EXPECT_THAT(unlong_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_UnSignedLong_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "6e74e284-7f13-4d77-8d3f-009df216828f"); + + constexpr bool IS_32_BIT{sizeof(long) != sizeof(long long)}; + + std::string source = "-1"; + auto unlong_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_min_dec_1.has_value(), Eq(false)); + + source = IS_32_BIT ? "4294967296" : "18446744073709551616"; + auto unlong_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_max_inc_1.has_value(), Eq(false)); +} + +TEST_F(convert_test, fromString_UnSignedLongLong_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "b3c70efd-f875-45bd-b86c-126dc44d3238"); + + std::string source = "0"; + auto unlong_long_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_long_min.has_value(), Eq(true)); + EXPECT_THAT(unlong_long_min.value(), Eq(0)); + + source = "18446744073709551615"; + auto unlong_long_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_long_max.has_value(), Eq(true)); + EXPECT_THAT(unlong_long_max.value(), Eq(std::numeric_limits::max())); } -TEST_F(convert_test, fromString_cxxString) +TEST_F(convert_test, fromString_UnSignedLongLong_EdgeCase_OutOfRange_Fail) +{ + ::testing::Test::RecordProperty("TEST_ID", "96456d6f-2493-4db2-b5fa-f96f92ec64dd"); + + std::string source = "-1"; + auto unlong_long_min_dec_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_long_min_dec_1.has_value(), Eq(false)); + + source = "18446744073709551616"; + auto unlong_long_max_inc_1 = iox::convert::from_string(source.c_str()); + ASSERT_THAT(unlong_long_max_inc_1.has_value(), Eq(false)); +} + +/// UNSINGED INTEGRAL EDGE CASES END + +/// NORMAL FLOATING POINT TYPE EDGE CASES START + +TEST_F(convert_test, fromString_Float_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "cf849d5d-d0ed-4447-89b8-d6b9f47287c7"); + + std::string source = fp_to_string(std::numeric_limits::min()); + auto float_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(float_min.has_value(), Eq(true)); + EXPECT_THAT(float_min.value(), FloatEq(std::numeric_limits::min())); + + source = fp_to_string(std::numeric_limits::lowest()); + auto float_lowest = iox::convert::from_string(source.c_str()); + ASSERT_THAT(float_lowest.has_value(), Eq(true)); + EXPECT_THAT(float_lowest.value(), FloatEq(std::numeric_limits::lowest())); + + source = fp_to_string(std::numeric_limits::max()); + auto float_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(float_max.has_value(), Eq(true)); + EXPECT_THAT(float_max.value(), FloatEq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_Float_EdgeCase_SubNormalFloat_ShouldFailExceptMsvc) +{ + ::testing::Test::RecordProperty("TEST_ID", "68d4f096-a93c-406b-b081-fe50e4b1a2c9"); + + // strtof will trigger ERANGE if the input is a subnormal float, resulting in a nullopt return value. + // note that for MSVC, sub normal float is a valid input! + auto normal_float_min_eps = std::nextafter(std::numeric_limits::min(), 0.0F); + std::string source = fp_to_string(std::numeric_limits::min() - normal_float_min_eps); + auto float_min_dec_eps = iox::convert::from_string(source.c_str()); +#ifdef _MSC_VER + ASSERT_THAT(float_min_dec_eps.has_value(), Eq(true)); + ASSERT_THAT(std::fpclassify(float_min_dec_eps.value()), Eq(FP_SUBNORMAL)); + EXPECT_THAT(float_min_dec_eps.value(), FloatNear(0.0F, std::numeric_limits::min())); +#else + ASSERT_THAT(float_min_dec_eps.has_value(), Eq(false)); +#endif +} + +TEST_F(convert_test, fromString_Double_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "d5e5e5ad-92ed-4229-8128-4ee82059fbf7"); + + std::string source = fp_to_string(std::numeric_limits::min()); + auto double_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(double_min.has_value(), Eq(true)); + EXPECT_THAT(double_min.value(), DoubleEq(std::numeric_limits::min())); + + source = fp_to_string(std::numeric_limits::lowest()); + auto double_lowest = iox::convert::from_string(source.c_str()); + ASSERT_THAT(double_lowest.has_value(), Eq(true)); + EXPECT_THAT(double_lowest.value(), DoubleEq(std::numeric_limits::lowest())); + + source = fp_to_string(std::numeric_limits::max()); + auto double_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(double_max.has_value(), Eq(true)); + EXPECT_THAT(double_max.value(), DoubleEq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_Double_EdgeCase_SubNormalDouble_ShouldFailExceptMsvc) +{ + ::testing::Test::RecordProperty("TEST_ID", "af7ca2e6-ba7e-41f7-a321-5f68617d3566"); + + auto normal_double_min_eps = std::nextafter(std::numeric_limits::min(), 0.0); + std::string source = fp_to_string(std::numeric_limits::min() - normal_double_min_eps); + auto double_min_dec_eps = iox::convert::from_string(source.c_str()); +#ifdef _MSC_VER + ASSERT_THAT(double_min_dec_eps.has_value(), Eq(true)); + ASSERT_THAT(std::fpclassify(double_min_dec_eps.value()), Eq(FP_SUBNORMAL)); + EXPECT_THAT(double_min_dec_eps.value(), DoubleNear(0.0, std::numeric_limits::min())); +#else + ASSERT_THAT(double_min_dec_eps.has_value(), Eq(false)); +#endif +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_InRange_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "cab1c90b-1de0-4654-bbea-4bb4e55e4fc3"); + + std::string source = fp_to_string(std::numeric_limits::min()); + auto long_double_min = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_double_min.has_value(), Eq(true)); + // There's no LongDoubleEq + EXPECT_THAT(long_double_min.value(), Eq(std::numeric_limits::min())); + + source = fp_to_string(std::numeric_limits::lowest()); + auto long_double_lowest = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_double_lowest.has_value(), Eq(true)); + EXPECT_THAT(long_double_lowest.value(), Eq(std::numeric_limits::lowest())); + + source = fp_to_string(std::numeric_limits::max()); + auto long_double_max = iox::convert::from_string(source.c_str()); + ASSERT_THAT(long_double_max.has_value(), Eq(true)); + EXPECT_THAT(long_double_max.value(), Eq(std::numeric_limits::max())); +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_SubNormalLongDouble_ShouldFailExceptMsvc) +{ + ::testing::Test::RecordProperty("TEST_ID", "fb96e526-8fb6-4af9-87f0-dfd4193237a5"); + + auto normal_long_double_min_eps = std::nextafter(std::numeric_limits::min(), 0.0L); + std::string source = fp_to_string(std::numeric_limits::min() - normal_long_double_min_eps); + auto long_double_min_dec_eps = iox::convert::from_string(source.c_str()); +#ifdef _MSC_VER + ASSERT_THAT(long_double_min_dec_eps.has_value(), Eq(true)); + ASSERT_THAT(std::fpclassify(long_double_min_dec_eps.value()), Eq(FP_SUBNORMAL)); + // There's no LongDoubleNear + EXPECT_TRUE(std::fabsl(long_double_min_dec_eps.value() - 0.0L) <= std::numeric_limits::min()); +#else + ASSERT_THAT(long_double_min_dec_eps.has_value(), Eq(false)); +#endif +} + +/// NORMAL FLOATING POINT TYPE EDGE CASES END + +/// SPECIAL FLOATING POINT TYPE EDGE CASES START + +TEST_F(convert_test, fromString_Float_EdgeCase_Nan_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "772bcbc3-d55b-464f-873f-82754ad543f3"); + + std::vector nan_vec = {"NAN", "NaN", "nan"}; + + for (const auto& v : nan_vec) + { + auto nan_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(nan_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isnan(nan_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_Double_EdgeCase_Nan_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "a27c8575-658c-465d-a1a2-4f2f6b9a723a"); + + std::vector nan_vec = {"NAN", "NaN", "nan"}; + + for (const auto& v : nan_vec) + { + auto nan_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(nan_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isnan(nan_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_Nan_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "486f4e78-6000-4401-bb66-62d26b1d0cce"); + + std::vector nan_vec = {"NAN", "NaN", "nan"}; + + for (const auto& v : nan_vec) + { + auto nan_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(nan_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isnan(nan_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_Float_EdgeCase_Inf_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "82dba3ae-5802-4fbc-aa91-15f4a2953573"); + + std::vector inf_vec = { + "INF", "Inf", "inf", "INFINITY", "Infinity", "-INF", "-Inf", "-inf", "-INFINITY", "-Infinity"}; + + for (const auto& v : inf_vec) + { + auto inf_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(inf_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isinf(inf_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_Double_EdgeCase_Inf_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "e4ccd01d-b1d1-433e-ba04-548dcc479bb1"); + + std::vector inf_vec = { + "INF", "Inf", "inf", "INFINITY", "Infinity", "-INF", "-Inf", "-inf", "-INFINITY", "-Infinity"}; + + for (const auto& v : inf_vec) + { + auto inf_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(inf_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isinf(inf_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_Inf_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "6b8a3284-5f20-4cd6-9958-a2abb348ebe2"); + + std::vector inf_vec = { + "INF", "Inf", "inf", "INFINITY", "Infinity", "-INF", "-Inf", "-inf", "-INFINITY", "-Infinity"}; + + for (const auto& v : inf_vec) + { + auto inf_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(inf_ret.has_value(), Eq(true)); + ASSERT_THAT(std::isinf(inf_ret.value()), Eq(true)); + } +} + +TEST_F(convert_test, fromString_Float_EdgeCase_ZeroDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "4ac285f9-e107-4d74-8aca-5d87032794db"); + + std::vector decimal_notation_vec = {"0", "-0", ".0", "-.0", "0.0", "-0.0", "0.", "-0."}; + + for (const auto& v : decimal_notation_vec) + { + auto decimal_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.0F)); + } +} + +TEST_F(convert_test, fromString_Double_EdgeCase_ZeroDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "98938eaa-c472-4338-a153-5c2de9eb4940"); + + std::vector decimal_notation_vec = {"0", "-0", ".0", "-.0", "0.0", "-0.0", "0.", "-0."}; + + for (const auto& v : decimal_notation_vec) + { + auto decimal_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.0)); + } +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_ZeroDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "49fc0812-47c0-4815-8a15-a94a81493ea0"); + + std::vector decimal_notation_vec = {"0", "-0", ".0", "-.0", "0.0", "-0.0", "0.", "-0."}; + + for (const auto& v : decimal_notation_vec) + { + auto decimal_ret = iox::convert::from_string(v.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.0L)); + } +} + +TEST_F(convert_test, fromString_Float_EdgeCase_OtherDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "278ff5af-28bd-4c11-839e-160e148c5a64"); + + std::string source = ".1"; + + auto decimal_ret = iox::convert::from_string(source.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.1F)); +} + +TEST_F(convert_test, fromString_Double_EdgeCase_OtherDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "a8539f9a-1c7a-4d81-9a88-ef8a6630f065"); + + std::string source = ".1"; + + auto decimal_ret = iox::convert::from_string(source.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.1)); +} + +TEST_F(convert_test, fromString_LongDouble_EdgeCase_OtherDecimalNotation_Success) +{ + ::testing::Test::RecordProperty("TEST_ID", "d71ec687-aaab-45d5-aee5-2ec9a51602d0"); + + std::string source = ".1"; + + auto decimal_ret = iox::convert::from_string(source.c_str()); + ASSERT_THAT(decimal_ret.has_value(), Eq(true)); + ASSERT_THAT(decimal_ret.value(), Eq(0.1L)); +} + +/// SPECIAL FLOATING POINT TYPE EDGE CASES END + +TEST_F(convert_test, fromString_ioxString) { ::testing::Test::RecordProperty("TEST_ID", "dbf015bb-5f51-47e1-9d0e-0525f65e7803"); std::string source = "hello";