ソースを参照

Fix String::begins_with when both strings are empty

(cherry picked from commit 3026b566b0143977c1b184781ca9bcb37cac65b7)
Mika Viskari 1 年間 前
コミット
02e6c0ab95
2 ファイル変更42 行追加27 行削除
  1. 5 1
      core/string/ustring.cpp
  2. 37 26
      tests/core/string/test_string.h

+ 5 - 1
core/string/ustring.cpp

@@ -3329,10 +3329,14 @@ bool String::begins_with(const String &p_string) const {
 
 bool String::begins_with(const char *p_string) const {
 	int l = length();
-	if (l == 0 || !p_string) {
+	if (!p_string) {
 		return false;
 	}
 
+	if (l == 0) {
+		return *p_string == 0;
+	}
+
 	const char32_t *str = &operator[](0);
 	int i = 0;
 

+ 37 - 26
tests/core/string/test_string.h

@@ -579,48 +579,59 @@ struct test_27_data {
 
 TEST_CASE("[String] Begins with") {
 	test_27_data tc[] = {
+		// Test cases for true:
 		{ "res://foobar", "res://", true },
+		{ "abc", "abc", true },
+		{ "abc", "", true },
+		{ "", "", true },
+		// Test cases for false:
 		{ "res", "res://", false },
-		{ "abc", "abc", true }
+		{ "abcdef", "foo", false },
+		{ "abc", "ax", false },
+		{ "", "abc", false }
 	};
 	size_t count = sizeof(tc) / sizeof(tc[0]);
 	bool state = true;
-	for (size_t i = 0; state && i < count; ++i) {
+	for (size_t i = 0; i < count; ++i) {
 		String s = tc[i].data;
 		state = s.begins_with(tc[i].part) == tc[i].expected;
-		if (state) {
-			String sb = tc[i].part;
-			state = s.begins_with(sb) == tc[i].expected;
-		}
-		CHECK(state);
-		if (!state) {
-			break;
-		}
-	};
-	CHECK(state);
+		CHECK_MESSAGE(state, "first check failed at: ", i);
+
+		String sb = tc[i].part;
+		state = s.begins_with(sb) == tc[i].expected;
+		CHECK_MESSAGE(state, "second check failed at: ", i);
+	}
+
+	// Test "const char *" version also with nullptr.
+	String s("foo");
+	state = s.begins_with(nullptr) == false;
+	CHECK_MESSAGE(state, "nullptr check failed");
+
+	String empty("");
+	state = empty.begins_with(nullptr) == false;
+	CHECK_MESSAGE(state, "nullptr check with empty string failed");
 }
 
 TEST_CASE("[String] Ends with") {
 	test_27_data tc[] = {
+		// test cases for true:
 		{ "res://foobar", "foobar", true },
+		{ "abc", "abc", true },
+		{ "abc", "", true },
+		{ "", "", true },
+		// test cases for false:
 		{ "res", "res://", false },
-		{ "abc", "abc", true }
+		{ "", "abc", false },
+		{ "abcdef", "foo", false },
+		{ "abc", "xc", false }
 	};
 	size_t count = sizeof(tc) / sizeof(tc[0]);
-	bool state = true;
-	for (size_t i = 0; state && i < count; ++i) {
+	for (size_t i = 0; i < count; ++i) {
 		String s = tc[i].data;
-		state = s.ends_with(tc[i].part) == tc[i].expected;
-		if (state) {
-			String sb = tc[i].part;
-			state = s.ends_with(sb) == tc[i].expected;
-		}
-		CHECK(state);
-		if (!state) {
-			break;
-		}
-	};
-	CHECK(state);
+		String sb = tc[i].part;
+		bool state = s.ends_with(sb) == tc[i].expected;
+		CHECK_MESSAGE(state, "check failed at: ", i);
+	}
 }
 
 TEST_CASE("[String] format") {