From 0b860bb5dd6d2007db605291d239a6a9d41f57d1 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Mon, 23 Sep 2024 07:36:16 -0500 Subject: Installable library. --- test/test_deserialize_number.cpp | 503 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 503 insertions(+) create mode 100644 test/test_deserialize_number.cpp (limited to 'test/test_deserialize_number.cpp') diff --git a/test/test_deserialize_number.cpp b/test/test_deserialize_number.cpp new file mode 100644 index 0000000..6b3f85c --- /dev/null +++ b/test/test_deserialize_number.cpp @@ -0,0 +1,503 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fud_array.hpp" +#include "fud_string.hpp" + +#include "gtest/gtest.h" + +namespace fud { + +template +auto testStringToIntegerInvalid(Func&& func) +{ + Array backing{"7 13 42 0 08 010 0x08"}; + FudString extString{FudString::withBacking(backing)}; + StringView view{extString}; + StringView invalidView{extString}; + T number = 0; + ASSERT_EQ(std::forward(func)(view, nullptr, 0, nullptr), ExtNullPointer); + + invalidView.data = nullptr; + ASSERT_EQ(std::forward(func)(invalidView, &number, 1, nullptr), ExtNullPointer); + invalidView.data = view.data; + + invalidView.length = 0; + ASSERT_EQ(std::forward(func)(invalidView, &number, 0, nullptr), ExtInvalidInput); + ASSERT_EQ(std::forward(func)(view, &number, 1, nullptr), ExtInvalidInput); + ASSERT_EQ(std::forward(func)(view, &number, UINT8_MAX, nullptr), ExtInvalidInput); +} + +template +auto testStringToNumber( + Array& backing, + const Array& wordSizes, + const Array& statuses, + const Array& expectedValues, + Func&& func, + uint8_t radix) +{ + FudString extString{FudString::withBacking(backing)}; + StringView view{extString}; + T number = 0; + + ASSERT_EQ(std::forward(func)(view, &number, radix, nullptr), statuses[0]); + ASSERT_EQ(number, expectedValues[0]); + + size_t index = 0; + for (size_t idx = 0; idx < WordCount; ++idx) { + + T tempNumber{}; + if (std::forward(func)(view, &tempNumber, radix, &index) != statuses[idx]) { + printf( + "どうして? \"%s\" %ld %zu %ld\n", + view.data, + static_cast(expectedValues[idx]), + idx, + static_cast(tempNumber)); + if (idx > 0) { + printf("Test: \"%s\"\n", view.data - index); + } + } + EXPECT_EQ(std::forward(func)(view, &number, radix, &index), statuses[idx]); + if (statuses[idx] == ExtSuccess) { + ASSERT_EQ(number, expectedValues[idx]); + ASSERT_EQ(index, wordSizes[idx]); + } + + view.data += wordSizes[idx]; + view.length -= wordSizes[idx]; + } +} + +TEST(FudString, StringToUint8Invalid) +{ + testStringToIntegerInvalid(ext_string_to_uint8); +} + +TEST(FudString, StringToUint8RadixUnspec) +{ + Array backing{"7 13 42 0 018 010 0xFF 0xFF0 256"}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 42") - 1, + sizeof(" 0") - 1, + sizeof(" 01") - 1, + sizeof("8") - 1, + sizeof(" 010") - 1, + sizeof(" 0xFF") - 1, + sizeof(" 0xFF0") - 1, + sizeof(" 256") - 1}; + constexpr Array expectedValues{7, 13, 42, 0, 1, 8, 8, 0xFF, 0, 0}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint8, 0); +} + +TEST(FudString, StringToUint8Octal) +{ + Array backing{"7 13 42 0 018 010 377 0xFF0"}; + constexpr Array expectedValues{7, 8 + 3, 8 * 4 + 2, 0, 1, 0, 8, 255, 0, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 42") - 1, + sizeof(" 0") - 1, + sizeof(" 01") - 1, + sizeof("8") - 1, + sizeof(" 010") - 1, + sizeof(" 377") - 1, + sizeof(" 0") - 1, + sizeof("xFF0") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint8, ExtRadixOctal); +} + +TEST(FudString, StringToUint8Hex) +{ + Array backing{"7 13 0x42 0 018 010 FF 0xFF0"}; + constexpr Array expectedValues{7, 16 + 3, 16 * 4 + 2, 0, 16 + 8, 16, 255, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 0x42") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" FF") - 1, + sizeof(" 0xFF0") - 1}; + constexpr Array + statuses{ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint8, ExtRadixHexadecimal); +} + +TEST(FudString, StringToUint16Invalid) +{ + testStringToIntegerInvalid(ext_string_to_uint16); +} + +TEST(FudString, StringToUint16RadixUnspec) +{ + Array backing{ + "7 65535 0x42 0 010 0xFFFF 0xFFFF0"}; + constexpr Array expectedValues{7, 0xFFFF, 0x42, 0, 8, 0xFFFF, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 65535") - 1, + sizeof(" 0x42") - 1, + sizeof(" 0") - 1, + sizeof(" 010") - 1, + sizeof(" 0xFFFF") - 1, + sizeof(" 0xFFFF0") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint16, 0); +} + +TEST(FudString, StringToUint16Octal) +{ + Array backing{"7 13 42 0 010 177777 200000"}; + constexpr Array expectedValues{7, 8 + 3, 8 * 4 + 2, 0, 8, 0xFFFF, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 42") - 1, + sizeof(" 0") - 1, + sizeof(" 010") - 1, + sizeof(" 177777") - 1, + sizeof(" 200000") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint16, ExtRadixOctal); +} + +TEST(FudString, StringToUint16Hex) +{ + Array backing{"7 13 0x42 0 018 010 FFFF 0x10000"}; + constexpr Array expectedValues{7, 16 + 3, 16 * 4 + 2, 0, 16 + 8, 16, 0xFFFF, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 0x42") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" FFFF") - 1, + sizeof(" 200000") - 1}; + constexpr Array + statuses{ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint16, ExtRadixHexadecimal); +} + +TEST(FudString, StringToUint64Hex) +{ + Array + backing{"7 13 0x7FFFFFFFFFFFFFFF 0 018 010 -8000000000000000 0xFFFFFFFFFFFFFFFF -8000000000000001"}; + constexpr Array expectedValues{ + 7, + 16 + 3, + std::numeric_limits::max(), + 0, + 16 + 8, + 16, + 0, + std::numeric_limits::max(), + 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 0x7FFFFFFFFFFFFFFF") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -8000000000000000") - 1, + sizeof(" 0xFFFFFFFFFFFFFFFF") - 1, + sizeof(" -8000000000000001") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtSuccess, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_uint64, ExtRadixHexadecimal); +} + +TEST(FudString, StringToInt8Invalid) +{ + testStringToIntegerInvalid(ext_string_to_int8); +} + +TEST(FudString, StringToInt8RadixUnspec) +{ + Array backing{"7 13 127 0 018 010 -0x80 0x80"}; + constexpr Array expectedValues{7, 13, 127, 0, 0, 8, -0x80, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 127") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -0x80") - 1, + sizeof(" 0x80") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtSuccess, + ExtSuccess, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_int8, 0); +} + +TEST(FudString, StringToInt8Octal) +{ + Array backing{"7 13 177 0 018 010 -200 0xFF0 -201"}; + constexpr Array expectedValues{7, 8 + 3, 127, 0, 0, 8, -128, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 177") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -200") - 1, + sizeof(" 0xFF0") - 1, + sizeof(" -201") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_int8, ExtRadixOctal); +} + +TEST(FudString, StringToInt8Hex) +{ + Array backing{"7 13 0x7F 0 018 010 -80 0xFF0"}; + constexpr Array expectedValues{7, 16 + 3, 127, 0, 16 + 8, 16, -128, 0}; + constexpr Array wordSizes{ + sizeof("7") - 1, + sizeof(" 13") - 1, + sizeof(" 0x7F") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -80") - 1, + sizeof(" 0xFF0") - 1}; + constexpr Array + statuses{ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_int8, ExtRadixHexadecimal); +} + +TEST(FudString, StringToInt32Decimal) +{ + Array backing{"01 13 0x7F 0 018 010 -80 0xFF0"}; + constexpr Array expectedValues{1, 13, 0, 0, 18, 10, -80, 0}; + constexpr Array wordSizes{ + sizeof("01") - 1, + sizeof(" 13") - 1, + sizeof(" 0x7F") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -80") - 1, + sizeof(" 0xFF0") - 1}; + constexpr Array + statuses{ExtSuccess, ExtSuccess, ExtInvalidInput, ExtSuccess, ExtSuccess, ExtSuccess, ExtSuccess, ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_int8, ExtRadixDecimal); +} + +TEST(FudString, StringToInt64Hex) +{ + Array + backing{"+7 13 0x7FFFFFFFFFFFFFFF 0 018 010 -8000000000000000 0x8000000000000000 -8000000000000001"}; + constexpr Array expectedValues{ + 7, + 16 + 3, + std::numeric_limits::max(), + 0, + 16 + 8, + 16, + std::numeric_limits::min(), + 0, + 0}; + constexpr Array wordSizes{ + sizeof("+7") - 1, + sizeof(" 13") - 1, + sizeof(" 0x7FFFFFFFFFFFFFFF") - 1, + sizeof(" 0") - 1, + sizeof(" 018") - 1, + sizeof(" 010") - 1, + sizeof(" -8000000000000000") - 1, + sizeof(" 0x8000000000000000") - 1, + sizeof(" -8000000000000001") - 1}; + constexpr Array statuses{ + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtSuccess, + ExtInvalidInput, + ExtInvalidInput}; + testStringToNumber(backing, wordSizes, statuses, expectedValues, ext_string_to_int64, ExtRadixHexadecimal); +} + +template +struct TestStringToFloatParams { + T value{0.0}; + size_t wordSize{0}; + ExtStatus status{ExtInvalidInput}; + bool isNaN{false}; +}; + +template +auto testStringToFloat( + Array& backing, + const Array, WordCount>& testParams, + Func&& func) +{ + FudString extString{FudString::withBacking(backing)}; + StringView view{extString}; + T number = 0; + + ASSERT_EQ(std::forward(func)(view, &number, nullptr), testParams[0].status); + ASSERT_EQ(number, testParams[0].value); + + size_t index = 0; + for (size_t idx = 0; idx < WordCount; ++idx) { + ASSERT_EQ(std::forward(func)(view, &number, &index), testParams[idx].status); + if (testParams[idx].status == ExtSuccess) { + if (!testParams[idx].isNaN) { + ASSERT_EQ(number, testParams[idx].value); + } else { + ASSERT_NE(number, number); + } + ASSERT_EQ(index, testParams[idx].wordSize); + } + + view.data += testParams[idx].wordSize; + view.length -= testParams[idx].wordSize; + } +} + +TEST(FudString, StringToFloat) +{ + Array backing{ + "123 -7 123.5 .25 0.25 -.125 -2.0625 NaN -inf inF"}; + /* N.B. In the following expressions, sizeof includes null, but excludes one leading space. */ + constexpr Array, 10> testParams{ + {{123.0, sizeof("123") - 1, ExtSuccess}, + {-7.0, sizeof("-7"), ExtSuccess}, + {123.5, sizeof("123.5"), ExtSuccess}, + {.25, sizeof(".25"), ExtSuccess}, + {.25, sizeof("0.25"), ExtSuccess}, + {-.125, sizeof("-.125"), ExtSuccess}, + {-2.0625, sizeof("-2.0625"), ExtSuccess}, + {std::numeric_limits::quiet_NaN(), sizeof("NaN"), ExtSuccess, true}, + {-1.0F * std::numeric_limits::infinity(), sizeof("-inf"), ExtSuccess}, + {std::numeric_limits::infinity(), sizeof("inF"), ExtSuccess}}}; + + testStringToFloat(backing, testParams, ext_string_to_float); +} + +TEST(FudString, StringToDouble) +{ + Array backing{ + "123 -7 123.5 .25 0.25 -.125 -2.0625 NaN -inf inF"}; + /* N.B. In the following expressions, sizeof includes null, but excludes one leading space. */ + constexpr Array, 10> testParams{ + {{123.0, sizeof("123") - 1, ExtSuccess}, + {-7.0, sizeof("-7"), ExtSuccess}, + {123.5, sizeof("123.5"), ExtSuccess}, + {.25, sizeof(".25"), ExtSuccess}, + {.25, sizeof("0.25"), ExtSuccess}, + {-.125, sizeof("-.125"), ExtSuccess}, + {-2.0625, sizeof("-2.0625"), ExtSuccess}, + {std::numeric_limits::quiet_NaN(), sizeof("NaN"), ExtSuccess, true}, + {-1.0 * std::numeric_limits::infinity(), sizeof("-inf"), ExtSuccess}, + {std::numeric_limits::infinity(), sizeof("inF"), ExtSuccess}}}; + + testStringToFloat(backing, testParams, ext_string_to_double); +} + +TEST(FudString, StringToDoubleExpt) +{ + Array backing{ + "1.25e01 1.25e+01 0.125e2 12.5e0 125.e-1 125e-1 1250.e-02 1250.0e-02"}; + /* N.B. In the following expressions, sizeof includes null, but excludes one leading space. */ + constexpr Array, 8> testParams{ + {{12.5, sizeof("1.25e01") - 1, ExtSuccess}, + {12.5, sizeof("1.25e+01"), ExtSuccess}, + {12.5, sizeof("0.125e2"), ExtSuccess}, + {12.5, sizeof("12.5e0"), ExtSuccess}, + {12.5, sizeof("125.e-1"), ExtSuccess}, + {12.5, sizeof("125e-1"), ExtSuccess}, + {12.5, sizeof("1250.e-02"), ExtSuccess}, + {12.5, sizeof("1250.0e-02"), ExtSuccess} + }}; + + testStringToFloat(backing, testParams, ext_string_to_double); +} + + +} // namespace fud -- cgit v1.2.3