feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -389,6 +389,19 @@ TEST_CASE("[String] Find") {
MULTICHECK_STRING_INT_EQ(s, rfind, "", 15, -1);
}
TEST_CASE("[String] Find character") {
String s = "racecar";
CHECK_EQ(s.find_char('r'), 0);
CHECK_EQ(s.find_char('r', 1), 6);
CHECK_EQ(s.find_char('e'), 3);
CHECK_EQ(s.find_char('e', 4), -1);
CHECK_EQ(s.rfind_char('r'), 6);
CHECK_EQ(s.rfind_char('r', 5), 0);
CHECK_EQ(s.rfind_char('e'), 3);
CHECK_EQ(s.rfind_char('e', 2), -1);
}
TEST_CASE("[String] Find case insensitive") {
String s = "Pretty Whale Whale";
MULTICHECK_STRING_EQ(s, findn, "WHA", 7);
@ -433,6 +446,19 @@ TEST_CASE("[String] Insertion") {
String s = "Who is Frederic?";
s = s.insert(s.find("?"), " Chopin");
CHECK(s == "Who is Frederic Chopin?");
s = "foobar";
CHECK(s.insert(0, "X") == "Xfoobar");
CHECK(s.insert(-100, "X") == "foobar");
CHECK(s.insert(6, "X") == "foobarX");
CHECK(s.insert(100, "X") == "foobarX");
CHECK(s.insert(2, "") == "foobar");
s = "";
CHECK(s.insert(0, "abc") == "abc");
CHECK(s.insert(100, "abc") == "abc");
CHECK(s.insert(-100, "abc") == "");
CHECK(s.insert(0, "") == "");
}
TEST_CASE("[String] Erasing") {
@ -442,16 +468,32 @@ TEST_CASE("[String] Erasing") {
}
TEST_CASE("[String] Number to string") {
CHECK(String::num(0) == "0");
CHECK(String::num(0.0) == "0"); // No trailing zeros.
CHECK(String::num(-0.0) == "-0"); // Includes sign even for zero.
CHECK(String::num(0) == "0.0"); // The method takes double, so always add zeros.
CHECK(String::num(0.0) == "0.0");
CHECK(String::num(-0.0) == "-0.0"); // Includes sign even for zero.
CHECK(String::num(3.141593) == "3.141593");
CHECK(String::num(3.141593, 3) == "3.142");
CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros.
CHECK(String::num_scientific(30000000) == "3e+07");
// String::num_int64 tests.
CHECK(String::num_int64(3141593) == "3141593");
CHECK(String::num_int64(-3141593) == "-3141593");
CHECK(String::num_int64(0xA141593, 16) == "a141593");
CHECK(String::num_int64(0xA141593, 16, true) == "A141593");
CHECK(String::num(42.100023, 4) == "42.1"); // No trailing zeros.
ERR_PRINT_OFF;
CHECK(String::num_int64(3141593, 1) == ""); // Invalid base < 2.
CHECK(String::num_int64(3141593, 37) == ""); // Invalid base > 36.
ERR_PRINT_ON;
// String::num_uint64 tests.
CHECK(String::num_uint64(4294967295) == "4294967295");
CHECK(String::num_uint64(0xF141593, 16) == "f141593");
CHECK(String::num_uint64(0xF141593, 16, true) == "F141593");
ERR_PRINT_OFF;
CHECK(String::num_uint64(4294967295, 1) == ""); // Invalid base < 2.
CHECK(String::num_uint64(4294967295, 37) == ""); // Invalid base > 36.
ERR_PRINT_ON;
// String::num_real tests.
CHECK(String::num_real(1.0) == "1.0");
@ -463,15 +505,15 @@ TEST_CASE("[String] Number to string") {
CHECK(String::num_real(3.141593) == "3.141593");
CHECK(String::num_real(3.141) == "3.141"); // No trailing zeros.
#ifdef REAL_T_IS_DOUBLE
CHECK_MESSAGE(String::num_real(123.456789) == "123.456789", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(-123.456789) == "-123.456789", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(Math_PI) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(3.1415f) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero.");
CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.456789", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.456789", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.14159265358979", "Prints the appropriate amount of digits for real_t = double.");
CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1414999961853", "Prints more digits of 32-bit float when real_t = double (ones that would be reliable for double) and no trailing zero.");
#else
CHECK_MESSAGE(String::num_real(123.456789) == "123.4568", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(-123.456789) == "-123.4568", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(Math_PI) == "3.141593", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(3.1415f) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float.");
CHECK_MESSAGE(String::num_real(real_t(123.456789)) == "123.4568", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(real_t(-123.456789)) == "-123.4568", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(real_t(Math_PI)) == "3.141593", "Prints the appropriate amount of digits for real_t = float.");
CHECK_MESSAGE(String::num_real(real_t(3.1415f)) == "3.1415", "Prints only reliable digits of 32-bit float when real_t = float.");
#endif // REAL_T_IS_DOUBLE
// Checks doubles with many decimal places.
@ -480,7 +522,7 @@ TEST_CASE("[String] Number to string") {
CHECK(String::num(-0.0000012345432123454321) == "-0.00000123454321");
CHECK(String::num(-10000.0000012345432123454321) == "-10000.0000012345");
CHECK(String::num(0.0000000000012345432123454321) == "0.00000000000123");
CHECK(String::num(0.0000000000012345432123454321, 3) == "0");
CHECK(String::num(0.0000000000012345432123454321, 3) == "0.0");
// Note: When relevant (remainder > 0.5), the last digit gets rounded up,
// which can also lead to not include a trailing zero, e.g. "...89" -> "...9".
@ -503,7 +545,10 @@ TEST_CASE("[String] String to integer") {
CHECK(String(nums[i]).to_int() == num[i]);
}
CHECK(String("0b1011").to_int() == 1011); // Looks like a binary number, but to_int() handles this as a base-10 number, "b" is just ignored.
CHECK(String("0B1011").to_int() == 1011);
CHECK(String("0x1012").to_int() == 1012); // Looks like a hexadecimal number, but to_int() handles this as a base-10 number, "x" is just ignored.
CHECK(String("0X1012").to_int() == 1012);
ERR_PRINT_OFF
CHECK(String("999999999999999999999999999999999999999999999999999999999").to_int() == INT64_MAX); // Too large, largest possible is returned.
@ -512,10 +557,10 @@ TEST_CASE("[String] String to integer") {
}
TEST_CASE("[String] Hex to integer") {
static const char *nums[12] = { "0xFFAE", "22", "0", "AADDAD", "0x7FFFFFFFFFFFFFFF", "-0xf", "", "000", "000f", "0xaA", "-ff", "-" };
static const int64_t num[12] = { 0xFFAE, 0x22, 0, 0xAADDAD, 0x7FFFFFFFFFFFFFFF, -0xf, 0, 0, 0xf, 0xaa, -0xff, 0x0 };
static const char *nums[13] = { "0xFFAE", "22", "0", "AADDAD", "0x7FFFFFFFFFFFFFFF", "-0xf", "", "000", "000f", "0xaA", "-ff", "-", "0XFFAE" };
static const int64_t num[13] = { 0xFFAE, 0x22, 0, 0xAADDAD, 0x7FFFFFFFFFFFFFFF, -0xf, 0, 0, 0xf, 0xaa, -0xff, 0x0, 0xFFAE };
for (int i = 0; i < 12; i++) {
for (int i = 0; i < 13; i++) {
CHECK(String(nums[i]).hex_to_int() == num[i]);
}
@ -533,10 +578,10 @@ TEST_CASE("[String] Hex to integer") {
}
TEST_CASE("[String] Bin to integer") {
static const char *nums[10] = { "", "0", "0b0", "0b1", "0b", "1", "0b1010", "-0b11", "-1010", "0b0111111111111111111111111111111111111111111111111111111111111111" };
static const int64_t num[10] = { 0, 0, 0, 1, 0, 1, 10, -3, -10, 0x7FFFFFFFFFFFFFFF };
static const char *nums[11] = { "", "0", "0b0", "0b1", "0b", "1", "0b1010", "-0b11", "-1010", "0b0111111111111111111111111111111111111111111111111111111111111111", "0B1010" };
static const int64_t num[11] = { 0, 0, 0, 1, 0, 1, 10, -3, -10, 0x7FFFFFFFFFFFFFFF, 10 };
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 11; i++) {
CHECK(String(nums[i]).bin_to_int() == num[i]);
}
@ -638,64 +683,90 @@ TEST_CASE("[String] Ends with") {
}
TEST_CASE("[String] Splitting") {
String s = "Mars,Jupiter,Saturn,Uranus";
const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" };
MULTICHECK_SPLIT(s, split, ",", true, 2, slices_l, 3);
{
const String s = "Mars,Jupiter,Saturn,Uranus";
const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" };
MULTICHECK_SPLIT(s, rsplit, ",", true, 2, slices_r, 3);
const char *slices_l[3] = { "Mars", "Jupiter", "Saturn,Uranus" };
MULTICHECK_SPLIT(s, split, ",", true, 2, slices_l, 3);
s = "test";
const char *slices_3[4] = { "t", "e", "s", "t" };
MULTICHECK_SPLIT(s, split, "", true, 0, slices_3, 4);
s = "";
const char *slices_4[1] = { "" };
MULTICHECK_SPLIT(s, split, "", true, 0, slices_4, 1);
MULTICHECK_SPLIT(s, split, "", false, 0, slices_4, 0);
s = "Mars Jupiter Saturn Uranus";
const char *slices_s[4] = { "Mars", "Jupiter", "Saturn", "Uranus" };
Vector<String> l = s.split_spaces();
for (int i = 0; i < l.size(); i++) {
CHECK(l[i] == slices_s[i]);
const char *slices_r[3] = { "Mars,Jupiter", "Saturn", "Uranus" };
MULTICHECK_SPLIT(s, rsplit, ",", true, 2, slices_r, 3);
}
s = "1.2;2.3 4.5";
const double slices_d[3] = { 1.2, 2.3, 4.5 };
Vector<double> d_arr;
d_arr = s.split_floats(";");
CHECK(d_arr.size() == 2);
for (int i = 0; i < d_arr.size(); i++) {
CHECK(ABS(d_arr[i] - slices_d[i]) <= 0.00001);
{
const String s = "test";
const char *slices[4] = { "t", "e", "s", "t" };
MULTICHECK_SPLIT(s, split, "", true, 0, slices, 4);
}
Vector<String> keys;
keys.push_back(";");
keys.push_back(" ");
Vector<float> f_arr;
f_arr = s.split_floats_mk(keys);
CHECK(f_arr.size() == 3);
for (int i = 0; i < f_arr.size(); i++) {
CHECK(ABS(f_arr[i] - slices_d[i]) <= 0.00001);
{
const String s = "";
const char *slices[1] = { "" };
MULTICHECK_SPLIT(s, split, "", true, 0, slices, 1);
MULTICHECK_SPLIT(s, split, "", false, 0, slices, 0);
}
s = "1;2 4";
const int slices_i[3] = { 1, 2, 4 };
Vector<int> ii;
ii = s.split_ints(";");
CHECK(ii.size() == 2);
for (int i = 0; i < ii.size(); i++) {
CHECK(ii[i] == slices_i[i]);
{
const String s = "Mars Jupiter Saturn Uranus";
const char *slices[4] = { "Mars", "Jupiter", "Saturn", "Uranus" };
Vector<String> l = s.split_spaces();
for (int i = 0; i < l.size(); i++) {
CHECK(l[i] == slices[i]);
}
}
ii = s.split_ints_mk(keys);
CHECK(ii.size() == 3);
for (int i = 0; i < ii.size(); i++) {
CHECK(ii[i] == slices_i[i]);
{
const String s = "1.2;2.3 4.5";
const double slices[3] = { 1.2, 2.3, 4.5 };
const Vector<double> d_arr = s.split_floats(";");
CHECK(d_arr.size() == 2);
for (int i = 0; i < d_arr.size(); i++) {
CHECK(ABS(d_arr[i] - slices[i]) <= 0.00001);
}
const Vector<String> keys = { ";", " " };
const Vector<float> f_arr = s.split_floats_mk(keys);
CHECK(f_arr.size() == 3);
for (int i = 0; i < f_arr.size(); i++) {
CHECK(ABS(f_arr[i] - slices[i]) <= 0.00001);
}
}
{
const String s = " -2.0 5";
const double slices[10] = { 0, -2, 0, 0, 0, 0, 0, 0, 0, 5 };
const Vector<double> arr = s.split_floats(" ");
CHECK(arr.size() == 10);
for (int i = 0; i < arr.size(); i++) {
CHECK(ABS(arr[i] - slices[i]) <= 0.00001);
}
const Vector<String> keys = { ";", " " };
const Vector<float> mk = s.split_floats_mk(keys);
CHECK(mk.size() == 10);
for (int i = 0; i < mk.size(); i++) {
CHECK(mk[i] == slices[i]);
}
}
{
const String s = "1;2 4";
const int slices[3] = { 1, 2, 4 };
const Vector<int> arr = s.split_ints(";");
CHECK(arr.size() == 2);
for (int i = 0; i < arr.size(); i++) {
CHECK(arr[i] == slices[i]);
}
const Vector<String> keys = { ";", " " };
const Vector<int> mk = s.split_ints_mk(keys);
CHECK(mk.size() == 3);
for (int i = 0; i < mk.size(); i++) {
CHECK(mk[i] == slices[i]);
}
}
}
@ -1199,6 +1270,12 @@ TEST_CASE("[String] is_subsequence_of") {
CHECK(String("Sub").is_subsequence_ofn(a));
}
TEST_CASE("[String] is_lowercase") {
CHECK(String("abcd1234 !@#$%^&*()_-=+,.<>/\\|[]{};':\"`~").is_lowercase());
CHECK(String("").is_lowercase());
CHECK(!String("abc_ABC").is_lowercase());
}
TEST_CASE("[String] match") {
CHECK(String("img1.png").match("*.png"));
CHECK(!String("img1.jpeg").match("*.png"));
@ -1594,7 +1671,7 @@ TEST_CASE("[String] Path functions") {
static const char *base_name[8] = { "C:\\Godot\\project\\test", "/Godot/project/test", "../Godot/project/test", "Godot\\test", "C:\\test", "res://test", "user://test", "/" };
static const char *ext[8] = { "tscn", "xscn", "scn", "doc", "", "", "", "test" };
static const char *file[8] = { "test.tscn", "test.xscn", "test.scn", "test.doc", "test.", "test", "test", ".test" };
static const char *simplified[8] = { "C:/Godot/project/test.tscn", "/Godot/project/test.xscn", "Godot/project/test.scn", "Godot/test.doc", "C:/test.", "res://test", "user://test", "/.test" };
static const char *simplified[8] = { "C:/Godot/project/test.tscn", "/Godot/project/test.xscn", "../Godot/project/test.scn", "Godot/test.doc", "C:/test.", "res://test", "user://test", "/.test" };
static const bool abs[8] = { true, true, false, false, true, true, true, true };
for (int i = 0; i < 8; i++) {
@ -1613,6 +1690,10 @@ TEST_CASE("[String] Path functions") {
for (int i = 0; i < 3; i++) {
CHECK(String(file_name[i]).is_valid_filename() == valid[i]);
}
CHECK(String("res://texture.png") == String("res://folder/../folder/../texture.png").simplify_path());
CHECK(String("res://texture.png") == String("res://folder/sub/../../texture.png").simplify_path());
CHECK(String("res://../../texture.png") == String("res://../../texture.png").simplify_path());
}
TEST_CASE("[String] hash") {
@ -1785,31 +1866,45 @@ TEST_CASE("[String] SHA1/SHA256/MD5") {
}
TEST_CASE("[String] Join") {
String s = ", ";
String comma = ", ";
String empty = "";
Vector<String> parts;
CHECK(comma.join(parts) == "");
CHECK(empty.join(parts) == "");
parts.push_back("One");
CHECK(comma.join(parts) == "One");
CHECK(empty.join(parts) == "One");
parts.push_back("B");
parts.push_back("C");
String t = s.join(parts);
CHECK(t == "One, B, C");
CHECK(comma.join(parts) == "One, B, C");
CHECK(empty.join(parts) == "OneBC");
parts.push_back("");
CHECK(comma.join(parts) == "One, B, C, ");
CHECK(empty.join(parts) == "OneBC");
}
TEST_CASE("[String] Is_*") {
static const char *data[12] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1" };
static bool isnum[12] = { true, true, true, false, false, false, false, false, false, false, false, false };
static bool isint[12] = { true, true, false, false, false, false, false, false, false, false, false, false };
static bool ishex[12] = { true, true, false, false, true, false, true, false, true, false, false, false };
static bool ishex_p[12] = { false, false, false, false, false, false, false, true, false, false, false, false };
static bool isflt[12] = { true, true, true, false, true, true, false, false, false, false, false, false };
static bool isid[12] = { false, false, false, false, false, false, false, false, true, true, false, false };
for (int i = 0; i < 12; i++) {
String s = String(data[i]);
static const char *data[] = { "-30", "100", "10.1", "10,1", "1e2", "1e-2", "1e2e3", "0xAB", "AB", "Test1", "1Test", "Test*1", "文字", "1E2", "1E-2" };
static bool isnum[] = { true, true, true, false, false, false, false, false, false, false, false, false, false, false, false };
static bool isint[] = { true, true, false, false, false, false, false, false, false, false, false, false, false, false, false };
static bool ishex[] = { true, true, false, false, true, false, true, false, true, false, false, false, false, true, false };
static bool ishex_p[] = { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false };
static bool isflt[] = { true, true, true, false, true, true, false, false, false, false, false, false, false, true, true };
static bool isaid[] = { false, false, false, false, false, false, false, false, true, true, false, false, false, false, false };
static bool isuid[] = { false, false, false, false, false, false, false, false, true, true, false, false, true, false, false };
for (unsigned int i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
String s = String::utf8(data[i]);
CHECK(s.is_numeric() == isnum[i]);
CHECK(s.is_valid_int() == isint[i]);
CHECK(s.is_valid_hex_number(false) == ishex[i]);
CHECK(s.is_valid_hex_number(true) == ishex_p[i]);
CHECK(s.is_valid_float() == isflt[i]);
CHECK(s.is_valid_identifier() == isid[i]);
CHECK(s.is_valid_ascii_identifier() == isaid[i]);
CHECK(s.is_valid_unicode_identifier() == isuid[i]);
}
}
@ -1835,18 +1930,32 @@ TEST_CASE("[String] validate_node_name") {
CHECK(name_with_invalid_chars.validate_node_name() == "Name with invalid characters ____removed!");
}
TEST_CASE("[String] validate_identifier") {
TEST_CASE("[String] validate_ascii_identifier") {
String empty_string;
CHECK(empty_string.validate_identifier() == "_");
CHECK(empty_string.validate_ascii_identifier() == "_");
String numeric_only = "12345";
CHECK(numeric_only.validate_identifier() == "_12345");
CHECK(numeric_only.validate_ascii_identifier() == "_12345");
String name_with_spaces = "Name with spaces";
CHECK(name_with_spaces.validate_identifier() == "Name_with_spaces");
CHECK(name_with_spaces.validate_ascii_identifier() == "Name_with_spaces");
String name_with_invalid_chars = U"Invalid characters:@*#&世界";
CHECK(name_with_invalid_chars.validate_identifier() == "Invalid_characters_______");
CHECK(name_with_invalid_chars.validate_ascii_identifier() == "Invalid_characters_______");
}
TEST_CASE("[String] validate_unicode_identifier") {
String empty_string;
CHECK(empty_string.validate_unicode_identifier() == "_");
String numeric_only = "12345";
CHECK(numeric_only.validate_unicode_identifier() == "_12345");
String name_with_spaces = "Name with spaces";
CHECK(name_with_spaces.validate_unicode_identifier() == "Name_with_spaces");
String name_with_invalid_chars = U"Invalid characters:@*#&世界";
CHECK(name_with_invalid_chars.validate_unicode_identifier() == U"Invalid_characters_____世界");
}
TEST_CASE("[String] Variant indexed get") {
@ -1921,6 +2030,61 @@ TEST_CASE("[String] Variant ptr indexed set") {
CHECK_EQ(s, String("azcd"));
}
TEST_CASE("[String][URL] Parse URL") {
#define CHECK_URL(m_url_to_parse, m_expected_schema, m_expected_host, m_expected_port, m_expected_path, m_expected_fragment, m_expected_error) \
if (true) { \
int port; \
String url(m_url_to_parse), schema, host, path, fragment; \
\
CHECK_EQ(url.parse_url(schema, host, port, path, fragment), m_expected_error); \
CHECK_EQ(schema, m_expected_schema); \
CHECK_EQ(host, m_expected_host); \
CHECK_EQ(path, m_expected_path); \
CHECK_EQ(fragment, m_expected_fragment); \
CHECK_EQ(port, m_expected_port); \
} else \
((void)0)
// All elements.
CHECK_URL("https://www.example.com:8080/path/to/file.html#fragment", "https://", "www.example.com", 8080, "/path/to/file.html", "fragment", Error::OK);
// Valid URLs.
CHECK_URL("https://godotengine.org", "https://", "godotengine.org", 0, "", "", Error::OK);
CHECK_URL("https://godotengine.org/", "https://", "godotengine.org", 0, "/", "", Error::OK);
CHECK_URL("godotengine.org/", "", "godotengine.org", 0, "/", "", Error::OK);
CHECK_URL("HTTPS://godotengine.org/", "https://", "godotengine.org", 0, "/", "", Error::OK);
CHECK_URL("https://GODOTENGINE.ORG/", "https://", "godotengine.org", 0, "/", "", Error::OK);
CHECK_URL("http://godotengine.org", "http://", "godotengine.org", 0, "", "", Error::OK);
CHECK_URL("https://godotengine.org:8080", "https://", "godotengine.org", 8080, "", "", Error::OK);
CHECK_URL("https://godotengine.org/blog", "https://", "godotengine.org", 0, "/blog", "", Error::OK);
CHECK_URL("https://godotengine.org/blog/", "https://", "godotengine.org", 0, "/blog/", "", Error::OK);
CHECK_URL("https://docs.godotengine.org/en/stable", "https://", "docs.godotengine.org", 0, "/en/stable", "", Error::OK);
CHECK_URL("https://docs.godotengine.org/en/stable/", "https://", "docs.godotengine.org", 0, "/en/stable/", "", Error::OK);
CHECK_URL("https://me:secret@godotengine.org", "https://", "godotengine.org", 0, "", "", Error::OK);
CHECK_URL("https://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/ipv6", "https://", "fedc:ba98:7654:3210:fedc:ba98:7654:3210", 0, "/ipv6", "", Error::OK);
// Scheme vs Fragment.
CHECK_URL("google.com/#goto=http://redirect_url/", "", "google.com", 0, "/", "goto=http://redirect_url/", Error::OK);
// Invalid URLs.
// Invalid Scheme.
CHECK_URL("https_://godotengine.org", "", "https_", 0, "//godotengine.org", "", Error::ERR_INVALID_PARAMETER);
// Multiple ports.
CHECK_URL("https://godotengine.org:8080:433", "https://", "", 0, "", "", Error::ERR_INVALID_PARAMETER);
// Missing ] on literal IPv6.
CHECK_URL("https://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/ipv6", "https://", "", 0, "/ipv6", "", Error::ERR_INVALID_PARAMETER);
// Missing host.
CHECK_URL("https:///blog", "https://", "", 0, "/blog", "", Error::ERR_INVALID_PARAMETER);
// Invalid ports.
CHECK_URL("https://godotengine.org:notaport", "https://", "godotengine.org", 0, "", "", Error::ERR_INVALID_PARAMETER);
CHECK_URL("https://godotengine.org:-8080", "https://", "godotengine.org", -8080, "", "", Error::ERR_INVALID_PARAMETER);
CHECK_URL("https://godotengine.org:88888", "https://", "godotengine.org", 88888, "", "", Error::ERR_INVALID_PARAMETER);
#undef CHECK_URL
}
TEST_CASE("[Stress][String] Empty via ' == String()'") {
for (int i = 0; i < 100000; ++i) {
String str = "Hello World!";