aboutsummaryrefslogtreecommitdiff
path: root/libc/test/src/__support/CPP/string_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libc/test/src/__support/CPP/string_test.cpp')
-rw-r--r--libc/test/src/__support/CPP/string_test.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/libc/test/src/__support/CPP/string_test.cpp b/libc/test/src/__support/CPP/string_test.cpp
new file mode 100644
index 0000000..f7a1821
--- /dev/null
+++ b/libc/test/src/__support/CPP/string_test.cpp
@@ -0,0 +1,204 @@
+//===-- Unittests for string ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/CPP/string.h"
+#include "test/UnitTest/Test.h"
+
+using __llvm_libc::cpp::string;
+using __llvm_libc::cpp::string_view;
+using __llvm_libc::cpp::to_string;
+
+TEST(LlvmLibcStringTest, InitializeEmpty) {
+ const string s;
+ ASSERT_EQ(s.size(), size_t(0));
+ ASSERT_TRUE(s.empty());
+ ASSERT_STREQ(s.data(), "");
+ ASSERT_STREQ(s.c_str(), "");
+ ASSERT_EQ(s.data(), s.c_str());
+ ASSERT_EQ(s.capacity(), size_t(0));
+}
+
+TEST(LlvmLibcStringTest, InitializeCString) {
+ const char *const str = "abc";
+ const string s(str);
+ ASSERT_EQ(s.size(), size_t(3));
+ ASSERT_FALSE(s.empty());
+ ASSERT_NE(s.data(), &str[0]);
+ ASSERT_EQ(s[0], 'a');
+ ASSERT_EQ(s[1], 'b');
+ ASSERT_EQ(s[2], 'c');
+ ASSERT_EQ(s.front(), 'a');
+ ASSERT_EQ(s.back(), 'c');
+ ASSERT_EQ(s.data(), s.c_str());
+}
+
+TEST(LlvmLibcStringTest, ToCString) {
+ const char *const str = "abc";
+ string s(str);
+ const char *cstr = s.c_str();
+ ASSERT_EQ(s.size(), size_t(3));
+ ASSERT_STREQ(str, cstr);
+}
+
+TEST(LlvmLibcStringTest, ToStringView) {
+ const char *const str = "abc";
+ string s(str);
+ string_view view = s;
+ ASSERT_EQ(view, string_view(str));
+}
+
+TEST(LlvmLibcStringTest, InitializeCStringWithSize) {
+ const char *const str = "abc";
+ const string s(str, 2);
+ ASSERT_EQ(s.size(), size_t(2));
+ ASSERT_EQ(s[0], 'a');
+ ASSERT_EQ(s[1], 'b');
+ ASSERT_EQ(s.front(), 'a');
+ ASSERT_EQ(s.back(), 'b');
+}
+
+TEST(LlvmLibcStringTest, InitializeRepeatedChar) {
+ const string s(4, '1');
+ ASSERT_EQ(string_view(s), string_view("1111"));
+}
+
+TEST(LlvmLibcStringTest, InitializeZeorChar) {
+ const string s(0, '1');
+ ASSERT_TRUE(s.empty());
+}
+
+TEST(LlvmLibcStringTest, CopyConstruct) {
+ const char *const str = "abc";
+ string a(str);
+ string b(a);
+ // Same content
+ ASSERT_STREQ(a.c_str(), str);
+ ASSERT_STREQ(b.c_str(), str);
+ // Different pointers
+ ASSERT_NE(a.data(), b.data());
+}
+
+string &&move(string &value) { return static_cast<string &&>(value); }
+
+TEST(LlvmLibcStringTest, CopyAssign) {
+ const char *const str = "abc";
+ string a(str);
+ string b;
+ b = a;
+ // Same content
+ ASSERT_STREQ(a.c_str(), str);
+ ASSERT_STREQ(b.c_str(), str);
+ // Different pointers
+ ASSERT_NE(a.data(), b.data());
+}
+
+TEST(LlvmLibcStringTest, MoveConstruct) {
+ const char *const str = "abc";
+ string a(str);
+ string b(move(a));
+ ASSERT_STREQ(b.c_str(), str);
+ ASSERT_STREQ(a.c_str(), "");
+}
+
+TEST(LlvmLibcStringTest, MoveAssign) {
+ const char *const str = "abc";
+ string a(str);
+ string b;
+ b = move(a);
+ ASSERT_STREQ(b.c_str(), str);
+ ASSERT_STREQ(a.c_str(), "");
+}
+
+TEST(LlvmLibcStringTest, Concat) {
+ const char *const str = "abc";
+ string a(str);
+ string b;
+ b += a;
+ ASSERT_STREQ(b.c_str(), "abc");
+ b += a;
+ ASSERT_STREQ(b.c_str(), "abcabc");
+}
+
+TEST(LlvmLibcStringTest, AddChar) {
+ string a;
+ a += 'a';
+ ASSERT_STREQ(a.c_str(), "a");
+ a += 'b';
+ ASSERT_STREQ(a.c_str(), "ab");
+}
+
+TEST(LlvmLibcStringTest, ResizeCapacityAndNullTermination) {
+ string a;
+ // Empty
+ ASSERT_EQ(a.capacity(), size_t(0));
+ ASSERT_EQ(a.data()[0], '\0');
+ // Still empty
+ a.resize(0);
+ ASSERT_EQ(a.capacity(), size_t(0));
+ ASSERT_EQ(a.data()[0], '\0');
+ // One char
+ a.resize(1);
+ ASSERT_EQ(a.size(), size_t(1));
+ ASSERT_GE(a.capacity(), size_t(2));
+ ASSERT_EQ(a.data()[1], '\0');
+ // Clear
+ a.resize(0);
+ ASSERT_EQ(a.size(), size_t(0));
+ ASSERT_GE(a.capacity(), size_t(2));
+ ASSERT_EQ(a.data()[0], '\0');
+ // Resize and check zero initialized
+ a.resize(10);
+ ASSERT_EQ(a.size(), size_t(10));
+ ASSERT_GE(a.capacity(), size_t(10));
+ for (size_t i = 0; i < 10; ++i)
+ ASSERT_EQ(a[i], '\0');
+}
+
+TEST(LlvmLibcStringTest, ConcatWithCString) {
+ ASSERT_STREQ((string("a") + string("b")).c_str(), "ab");
+ ASSERT_STREQ((string("a") + "b").c_str(), "ab");
+ ASSERT_STREQ(("a" + string("b")).c_str(), "ab");
+}
+
+TEST(LlvmLibcStringTest, Comparison) {
+ // Here we simply check that comparison of string and string_view have the
+ // same semantic.
+ struct CStringPair {
+ const char *const a;
+ const char *const b;
+ } kTestPairs[] = {{"a", "b"}, {"", "xyz"}};
+ for (const auto [pa, pb] : kTestPairs) {
+ const string sa(pa);
+ const string sb(pb);
+ const string_view sva(pa);
+ const string_view svb(pb);
+ ASSERT_EQ(sa == sb, sva == svb);
+ ASSERT_EQ(sa != sb, sva != svb);
+ ASSERT_EQ(sa >= sb, sva >= svb);
+ ASSERT_EQ(sa <= sb, sva <= svb);
+ ASSERT_EQ(sa < sb, sva < svb);
+ ASSERT_EQ(sa > sb, sva > svb);
+ }
+}
+
+TEST(LlvmLibcStringTest, ToString) {
+ struct CStringPair {
+ const int value;
+ const string str;
+ } kTestPairs[] = {{123, "123"}, {0, "0"}, {-321, "-321"}};
+ for (const auto &[value, str] : kTestPairs) {
+ ASSERT_EQ(to_string((int)(value)), str);
+ ASSERT_EQ(to_string((long)(value)), str);
+ ASSERT_EQ(to_string((long long)(value)), str);
+ if (value >= 0) {
+ ASSERT_EQ(to_string((unsigned int)(value)), str);
+ ASSERT_EQ(to_string((unsigned long)(value)), str);
+ ASSERT_EQ(to_string((unsigned long long)(value)), str);
+ }
+ }
+}