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

#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