1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/*!********************************************************************
Audacity: A Digital Audio Editor
@file FromCharsTests.cpp
@brief Tests for the FromChars functions
Dmitry Vedenko
**********************************************************************/
#include <catch2/catch.hpp>
#include <string>
#include <string_view>
#include <type_traits>
#include "FromChars.h"
template <typename T>
void TestFromChars(std::string_view input, T expectedValue, std::errc errc = {})
{
T value;
const auto result =
FromChars(input.data(), input.data() + input.length(), value);
REQUIRE(errc == result.ec);
if (errc == std::errc {})
{
if constexpr (std::is_floating_point_v<std::decay_t<T>>)
REQUIRE(Approx(expectedValue) == value);
else
REQUIRE(expectedValue == value);
REQUIRE(result.ptr == input.data() + input.length());
}
}
TEMPLATE_TEST_CASE(
"FromChars/signed integers", "", short, int, long, long long)
{
TestFromChars<TestType>("0", 0, {});
TestFromChars<TestType>("1", 1, {});
TestFromChars<TestType>("-1", -1, {});
TestFromChars<TestType>("127", 127, {});
TestFromChars<TestType>("-12", -12, {});
TestFromChars<TestType>("", {}, std::errc::invalid_argument);
TestFromChars<TestType>("a", {}, std::errc::invalid_argument);
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::min()),
std::numeric_limits<TestType>::min(), {});
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::max()),
std::numeric_limits<TestType>::max(), {});
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::min()) + "0",
std::numeric_limits<TestType>::min(), std::errc::result_out_of_range);
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::max()) + "0",
std::numeric_limits<TestType>::max(), std::errc::result_out_of_range);
}
TEMPLATE_TEST_CASE(
"FromChars/unsigned integers", "", unsigned short, unsigned int,
unsigned long, unsigned long long)
{
TestFromChars<TestType>("0", 0, {});
TestFromChars<TestType>("1", 1, {});
TestFromChars<TestType>("-1", -1, std::errc::invalid_argument);
TestFromChars<TestType>("127", 127, {});
TestFromChars<TestType>("-12", -12, std::errc::invalid_argument);
TestFromChars<TestType>("", {}, std::errc::invalid_argument);
TestFromChars<TestType>("a", {}, std::errc::invalid_argument);
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::min()),
std::numeric_limits<TestType>::min(), {});
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::max()),
std::numeric_limits<TestType>::max(), {});
TestFromChars<TestType>(
std::to_string(std::numeric_limits<TestType>::max()) + "0",
std::numeric_limits<TestType>::max(), std::errc::result_out_of_range);
}
TEMPLATE_TEST_CASE("FromChars/floats", "", float, double)
{
TestFromChars<TestType>("0", 0, {});
TestFromChars<TestType>("0.0", 0, {});
TestFromChars<TestType>(".0", 0, {});
TestFromChars<TestType>("1", 1, {});
TestFromChars<TestType>("-1", -1, {});
TestFromChars<TestType>("127", 127, {});
TestFromChars<TestType>("-12", -12, {});
TestFromChars<TestType>("-12.5", -12.5, {});
TestFromChars<TestType>("3.1415", 3.1415, {});
TestFromChars<TestType>("3.14159265359", 3.14159265359, {});
for (auto magnitude = std::numeric_limits<TestType>::min_exponent10;
magnitude <= std::numeric_limits<TestType>::max_exponent10; ++magnitude)
{
TestFromChars(
"1e" + std::to_string(magnitude), std::pow(10, magnitude), {});
TestFromChars(
"-1e" + std::to_string(magnitude), -std::pow(10, magnitude), {});
}
TestFromChars<TestType>("", {}, std::errc::invalid_argument);
TestFromChars<TestType>("a", {}, std::errc::invalid_argument);
TestFromChars<TestType>(
"1e1000", std::numeric_limits<TestType>::infinity(), {});
}
|