ladybird/Tests/LibWeb/TestNumbers.cpp
Jonatan Klemets 9812031a02 LibWeb: Implement spec-compliant integer parsing
We have code inside LibWeb that uses the
`AK::StringUtils::convert_to_uint`and `AK::StringUtils::convert_to_int`
methods for parsing integers. This works well for the most part, but
according to the spec, trailing characters are allowed and should be
ignored, but this is not how the `StringUtil` methods are implemented.

This patch adds two new methods named `parse_integer` and
`parse_non_negative_integer` inside the `Web::HTML` namespace that uses
`StringUtils` under the hood but adds a bit more logic to make it spec
compliant.
2023-08-24 22:26:53 +01:00

106 lines
3.5 KiB
C++

/*
* Copyright (c) 2023, Jonatan Klemets <jonatan.r.klemets@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <LibWeb/HTML/Numbers.h>
TEST_CASE(parse_integer)
{
auto optional_value = Web::HTML::parse_integer(""sv);
EXPECT(!optional_value.has_value());
optional_value = Web::HTML::parse_integer("123"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 123);
optional_value = Web::HTML::parse_integer(" 456"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 456);
optional_value = Web::HTML::parse_integer("789 "sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 789);
optional_value = Web::HTML::parse_integer(" 22 "sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 22);
optional_value = Web::HTML::parse_integer(" \n\t31\t\t\n\n"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 31);
optional_value = Web::HTML::parse_integer("765foo"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 765);
optional_value = Web::HTML::parse_integer("3;"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 3);
optional_value = Web::HTML::parse_integer("foo765"sv);
EXPECT(!optional_value.has_value());
optional_value = Web::HTML::parse_integer("1"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 1);
optional_value = Web::HTML::parse_integer("+2"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 2);
optional_value = Web::HTML::parse_integer("-3"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), -3);
}
TEST_CASE(parse_non_negative_integer)
{
auto optional_value = Web::HTML::parse_non_negative_integer(""sv);
EXPECT(!optional_value.has_value());
optional_value = Web::HTML::parse_non_negative_integer("123"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 123u);
optional_value = Web::HTML::parse_non_negative_integer(" 456"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 456u);
optional_value = Web::HTML::parse_non_negative_integer("789 "sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 789u);
optional_value = Web::HTML::parse_non_negative_integer(" 22 "sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 22u);
optional_value = Web::HTML::parse_non_negative_integer(" \n\t31\t\t\n\n"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 31u);
optional_value = Web::HTML::parse_non_negative_integer("765foo"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 765u);
optional_value = Web::HTML::parse_non_negative_integer("3;"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 3u);
optional_value = Web::HTML::parse_non_negative_integer("foo765"sv);
EXPECT(!optional_value.has_value());
optional_value = Web::HTML::parse_non_negative_integer("1"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 1u);
optional_value = Web::HTML::parse_non_negative_integer("+2"sv);
EXPECT(optional_value.has_value());
EXPECT_EQ(optional_value.value(), 2u);
optional_value = Web::HTML::parse_non_negative_integer("-3"sv);
EXPECT(!optional_value.has_value());
}