feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -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!";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue