You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
7.2 KiB
152 lines
7.2 KiB
|
3 years ago
|
#include <gtest/gtest.h>
|
||
|
|
|
||
|
|
#include "utils/parse_int.hpp"
|
||
|
|
|
||
|
|
namespace devilution {
|
||
|
|
TEST(ParseIntTest, ParseInt)
|
||
|
|
{
|
||
|
|
ParseIntResult<int> result = ParseInt<int>("");
|
||
|
|
ASSERT_FALSE(result.has_value());
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError);
|
||
|
|
|
||
|
|
result = ParseInt<int>("abcd");
|
||
|
|
ASSERT_FALSE(result.has_value());
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError);
|
||
|
|
|
||
|
|
result = ParseInt<int>("12");
|
||
|
|
ASSERT_TRUE(result.has_value());
|
||
|
|
EXPECT_EQ(result.value(), 12);
|
||
|
|
|
||
|
|
result = ParseInt<int>(("99999999"), -5, 100);
|
||
|
|
ASSERT_FALSE(result.has_value());
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::OutOfRange);
|
||
|
|
|
||
|
|
ParseIntResult<int8_t> shortResult = ParseInt<int8_t>(("99999999"));
|
||
|
|
ASSERT_FALSE(shortResult.has_value());
|
||
|
|
EXPECT_EQ(shortResult.error(), ParseIntError::OutOfRange);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(ParseIntTest, ParseFixed6Fraction)
|
||
|
|
{
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction(""), 0);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("0"), 0);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("00781249"), 0);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("0078125"), 1);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("015625"), 1);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("03125"), 2);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("046875"), 3);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("0625"), 4);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("078125"), 5);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("09375"), 6);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("109375"), 7);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("125"), 8);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("140625"), 9);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("15625"), 10);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("171875"), 11);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("1875"), 12);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("203125"), 13);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("21875"), 14);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("234375"), 15);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("25"), 16);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("265625"), 17);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("28125"), 18);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("296875"), 19);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("3125"), 20);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("328125"), 21);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("34375"), 22);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("359375"), 23);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("375"), 24);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("390625"), 25);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("40625"), 26);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("421875"), 27);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("4375"), 28);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("453125"), 29);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("46875"), 30);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("484375"), 31);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("5"), 32);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("515625"), 33);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("53125"), 34);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("546875"), 35);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("5625"), 36);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("578125"), 37);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("59375"), 38);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("609375"), 39);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("625"), 40);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("640625"), 41);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("65625"), 42);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("671875"), 43);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("6875"), 44);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("703125"), 45);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("71875"), 46);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("734375"), 47);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("75"), 48);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("765625"), 49);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("78125"), 50);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("796875"), 51);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("8125"), 52);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("828125"), 53);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("84375"), 54);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("859375"), 55);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("875"), 56);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("890625"), 57);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("90625"), 58);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("921875"), 59);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("9375"), 60);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("953125"), 61);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("96875"), 62);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("984375"), 63);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("99218749"), 63);
|
||
|
|
EXPECT_EQ(ParseFixed6Fraction("9921875"), 64);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(ParseInt, ParseFixed6)
|
||
|
|
{
|
||
|
|
ParseIntResult<int> result = ParseFixed6<int>("");
|
||
|
|
ASSERT_FALSE(result.has_value()) << "Empty strings are not valid fixed point values.";
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError) << "ParseFixed6 should give a ParseError code when parsing an empty string.";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("abcd");
|
||
|
|
ASSERT_FALSE(result.has_value()) << "Non-numeric strings should not be parsed as a fixed-point value.";
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError) << "ParseFixed6 should give a ParseError code when parsing a non-numeric string.";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>(".");
|
||
|
|
ASSERT_FALSE(result.has_value()) << "To match std::from_chars ParseFixed6 should fail to parse a decimal string with no digits.";
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError) << "Decimal strings with no digits are reported as ParseError codes.";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("1.");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "A trailing decimal point is permitted for fixed point values";
|
||
|
|
EXPECT_EQ(result.value(), 1 << 6);
|
||
|
|
|
||
|
|
result = ParseFixed6<int>(".5");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "A fixed point value with no integer part is accepted";
|
||
|
|
EXPECT_EQ(result.value(), 32);
|
||
|
|
|
||
|
|
std::string_view badString { "-." };
|
||
|
|
const char *endOfParse = nullptr;
|
||
|
|
result = ParseFixed6<int>(badString, &endOfParse);
|
||
|
|
ASSERT_FALSE(result.has_value()) << "To match std::from_chars ParseFixed6 should fail to parse a decimal string with no digits, even if it starts with a minus sign.";
|
||
|
|
EXPECT_EQ(result.error(), ParseIntError::ParseError) << "Decimal strings with no digits are reported as ParseError codes.";
|
||
|
|
EXPECT_EQ(endOfParse, badString.data()) << "Failed fixed point parsing should set the end pointer to match the start of the string even though it read multiple characters";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("-1.");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "negative fixed point values are handled when reading into signed types";
|
||
|
|
EXPECT_EQ(result.value(), -1 << 6);
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("-1.25");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "negative fixed point values are handled when reading into signed types";
|
||
|
|
EXPECT_EQ(result.value(), -((1 << 6) + 16)) << "and the fraction part is combined with the integer part respecting the sign";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("-.25");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "negative fixed point values with no integer digits are handled when reading into signed types";
|
||
|
|
EXPECT_EQ(result.value(), -16) << "and the fraction part is used respecting the sign";
|
||
|
|
|
||
|
|
result = ParseFixed6<int>("-0.25");
|
||
|
|
ASSERT_TRUE(result.has_value()) << "negative fixed point values with an explicit -0 integer part are handled when reading into signed types";
|
||
|
|
EXPECT_EQ(result.value(), -16) << "and the fraction part is used respecting the sign";
|
||
|
|
|
||
|
|
ParseIntResult<unsigned> unsignedResult = ParseFixed6<unsigned>("-1.");
|
||
|
|
ASSERT_FALSE(unsignedResult.has_value()) << "negative fixed point values are not permitted when reading into unsigned types";
|
||
|
|
EXPECT_EQ(unsignedResult.error(), ParseIntError::ParseError) << "Attempting to parse a negative value into an unsigned type is a ParseError, not an OutOfRange value";
|
||
|
|
}
|
||
|
|
} // namespace devilution
|