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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#include <hyprutils/string/Numeric.hpp>
#include <gtest/gtest.h>
#include <cstdint>
#include <limits>
using namespace Hyprutils::String;
TEST(Numeric, intSuccess) {
auto r = strToNumber<int>("42");
ASSERT_TRUE(r.has_value());
EXPECT_EQ(*r, 42);
auto neg = strToNumber<int>("-7");
ASSERT_TRUE(neg.has_value());
EXPECT_EQ(*neg, -7);
auto zero = strToNumber<int>("0");
ASSERT_TRUE(zero.has_value());
EXPECT_EQ(*zero, 0);
}
TEST(Numeric, intBounds) {
const auto maxStr = std::to_string(std::numeric_limits<int32_t>::max());
auto rMax = strToNumber<int32_t>(maxStr);
ASSERT_TRUE(rMax.has_value());
EXPECT_EQ(*rMax, std::numeric_limits<int32_t>::max());
const auto minStr = std::to_string(std::numeric_limits<int32_t>::min());
auto rMin = strToNumber<int32_t>(minStr);
ASSERT_TRUE(rMin.has_value());
EXPECT_EQ(*rMin, std::numeric_limits<int32_t>::min());
}
TEST(Numeric, outOfRange) {
auto r = strToNumber<int8_t>("999");
ASSERT_FALSE(r.has_value());
EXPECT_EQ(r.error(), NUMERIC_PARSE_OUT_OF_RANGE);
// from_chars rejects '-' for unsigned types as invalid argument, not out-of-range
auto r2 = strToNumber<uint8_t>("-1");
ASSERT_FALSE(r2.has_value());
EXPECT_EQ(r2.error(), NUMERIC_PARSE_BAD);
}
TEST(Numeric, garbage) {
auto r = strToNumber<int>("12abc");
ASSERT_FALSE(r.has_value());
EXPECT_EQ(r.error(), NUMERIC_PARSE_GARBAGE);
auto r2 = strToNumber<double>("1.0xyz");
ASSERT_FALSE(r2.has_value());
EXPECT_EQ(r2.error(), NUMERIC_PARSE_GARBAGE);
}
TEST(Numeric, bad) {
auto r = strToNumber<int>("");
ASSERT_FALSE(r.has_value());
EXPECT_EQ(r.error(), NUMERIC_PARSE_BAD);
auto r2 = strToNumber<int>("abc");
ASSERT_FALSE(r2.has_value());
EXPECT_EQ(r2.error(), NUMERIC_PARSE_BAD);
auto r3 = strToNumber<int>("--1");
ASSERT_FALSE(r3.has_value());
EXPECT_EQ(r3.error(), NUMERIC_PARSE_BAD);
}
TEST(Numeric, floatSuccess) {
auto r = strToNumber<double>("3.14");
ASSERT_TRUE(r.has_value());
EXPECT_DOUBLE_EQ(*r, 3.14);
auto neg = strToNumber<float>("-0.5");
ASSERT_TRUE(neg.has_value());
EXPECT_FLOAT_EQ(*neg, -0.5f);
auto whole = strToNumber<double>("100");
ASSERT_TRUE(whole.has_value());
EXPECT_DOUBLE_EQ(*whole, 100.0);
}
TEST(Numeric, unsignedTypes) {
auto r = strToNumber<uint64_t>("18446744073709551615");
ASSERT_TRUE(r.has_value());
EXPECT_EQ(*r, std::numeric_limits<uint64_t>::max());
auto r2 = strToNumber<uint32_t>("0");
ASSERT_TRUE(r2.has_value());
EXPECT_EQ(*r2, 0u);
}
TEST(Numeric, hexSuccess) {
auto r = strToNumber<int>("0xAF23");
ASSERT_TRUE(r.has_value());
EXPECT_EQ(*r, 0xAF23);
auto r2 = strToNumber<uint32_t>("0xFF");
ASSERT_TRUE(r2.has_value());
EXPECT_EQ(*r2, 0xFFu);
auto r3 = strToNumber<uint64_t>("0xDEADBEEF");
ASSERT_TRUE(r3.has_value());
EXPECT_EQ(*r3, 0xDEADBEEFu);
// uppercase X prefix
auto r4 = strToNumber<int>("0XFF");
ASSERT_TRUE(r4.has_value());
EXPECT_EQ(*r4, 0xFF);
// lowercase hex digits
auto r5 = strToNumber<uint32_t>("0xdeadbeef");
ASSERT_TRUE(r5.has_value());
EXPECT_EQ(*r5, 0xDEADBEEFu);
// zero value
auto r6 = strToNumber<int>("0x0");
ASSERT_TRUE(r6.has_value());
EXPECT_EQ(*r6, 0);
}
TEST(Numeric, hexErrors) {
// incomplete prefix (just "0x")
auto r = strToNumber<int>("0x");
ASSERT_FALSE(r.has_value());
EXPECT_EQ(r.error(), NUMERIC_PARSE_BAD);
// garbage after valid hex digits
auto r2 = strToNumber<int>("0xFF_ZZ");
ASSERT_FALSE(r2.has_value());
EXPECT_EQ(r2.error(), NUMERIC_PARSE_GARBAGE);
// out of range for type
auto r3 = strToNumber<uint8_t>("0xFFF");
ASSERT_FALSE(r3.has_value());
EXPECT_EQ(r3.error(), NUMERIC_PARSE_OUT_OF_RANGE);
// floats do not accept hex prefix
auto r4 = strToNumber<double>("0xFF");
ASSERT_FALSE(r4.has_value());
EXPECT_EQ(r4.error(), NUMERIC_PARSE_GARBAGE);
}
|