summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-03-08 09:06:59 -0500
committerLinus Groh <mail@linusgroh.de>2023-03-08 14:16:47 +0000
commit515fca4f7a756c1c40c7a52ca25560b12d2e948b (patch)
treeecb5987aebf830f01abfdf5d45e042ab2628d7f7
parentf882581e91c256a0400bbd262676580037dc30f4 (diff)
downloadserenity-515fca4f7a756c1c40c7a52ca25560b12d2e948b.zip
AK: Make String::contains(code_point) handle non-ASCII
We currently only accept a char, instead of a full code point.
-rw-r--r--AK/String.cpp5
-rw-r--r--AK/String.h2
-rw-r--r--Tests/AK/TestString.cpp46
3 files changed, 50 insertions, 3 deletions
diff --git a/AK/String.cpp b/AK/String.cpp
index 428684f9ca..005a53d192 100644
--- a/AK/String.cpp
+++ b/AK/String.cpp
@@ -489,9 +489,10 @@ bool String::contains(StringView needle, CaseSensitivity case_sensitivity) const
return StringUtils::contains(bytes_as_string_view(), needle, case_sensitivity);
}
-bool String::contains(char needle, CaseSensitivity case_sensitivity) const
+bool String::contains(u32 needle, CaseSensitivity case_sensitivity) const
{
- return contains(StringView { &needle, 1 }, case_sensitivity);
+ auto needle_as_string = String::from_code_point(needle);
+ return contains(needle_as_string.bytes_as_string_view(), case_sensitivity);
}
bool String::starts_with(u32 code_point) const
diff --git a/AK/String.h b/AK/String.h
index adbcd6da5b..71bb6e7ef2 100644
--- a/AK/String.h
+++ b/AK/String.h
@@ -172,7 +172,7 @@ public:
}
[[nodiscard]] bool contains(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
- [[nodiscard]] bool contains(char, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
+ [[nodiscard]] bool contains(u32, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
[[nodiscard]] u32 hash() const;
diff --git a/Tests/AK/TestString.cpp b/Tests/AK/TestString.cpp
index 305f22ee92..06318756ad 100644
--- a/Tests/AK/TestString.cpp
+++ b/Tests/AK/TestString.cpp
@@ -712,6 +712,52 @@ TEST_CASE(trim)
}
}
+TEST_CASE(contains)
+{
+ EXPECT(!String {}.contains({}));
+ EXPECT(!String {}.contains(" "sv));
+ EXPECT(!String {}.contains(0));
+
+ EXPECT("a"_short_string.contains("a"sv));
+ EXPECT(!"a"_short_string.contains({}));
+ EXPECT(!"a"_short_string.contains("b"sv));
+ EXPECT(!"a"_short_string.contains("ab"sv));
+
+ EXPECT("a"_short_string.contains(0x0061));
+ EXPECT(!"a"_short_string.contains(0x0062));
+
+ EXPECT("abc"_short_string.contains("a"sv));
+ EXPECT("abc"_short_string.contains("b"sv));
+ EXPECT("abc"_short_string.contains("c"sv));
+ EXPECT("abc"_short_string.contains("ab"sv));
+ EXPECT("abc"_short_string.contains("bc"sv));
+ EXPECT("abc"_short_string.contains("abc"sv));
+ EXPECT(!"abc"_short_string.contains({}));
+ EXPECT(!"abc"_short_string.contains("ac"sv));
+ EXPECT(!"abc"_short_string.contains("abcd"sv));
+
+ EXPECT("abc"_short_string.contains(0x0061));
+ EXPECT("abc"_short_string.contains(0x0062));
+ EXPECT("abc"_short_string.contains(0x0063));
+ EXPECT(!"abc"_short_string.contains(0x0064));
+
+ auto emoji = MUST("😀"_string);
+ EXPECT(emoji.contains("\xF0"sv));
+ EXPECT(emoji.contains("\x9F"sv));
+ EXPECT(emoji.contains("\x98"sv));
+ EXPECT(emoji.contains("\x80"sv));
+ EXPECT(emoji.contains("\xF0\x9F"sv));
+ EXPECT(emoji.contains("\xF0\x9F\x98"sv));
+ EXPECT(emoji.contains("\xF0\x9F\x98\x80"sv));
+ EXPECT(emoji.contains("\x9F\x98\x80"sv));
+ EXPECT(emoji.contains("\x98\x80"sv));
+ EXPECT(!emoji.contains("a"sv));
+ EXPECT(!emoji.contains("🙃"sv));
+
+ EXPECT(emoji.contains(0x1F600));
+ EXPECT(!emoji.contains(0x1F643));
+}
+
TEST_CASE(starts_with)
{
EXPECT(String {}.starts_with_bytes({}));