226 lines · cpp
1//===-- Unittests for string ----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/__support/CPP/string.h"10#include "test/UnitTest/Test.h"11 12using LIBC_NAMESPACE::cpp::string;13using LIBC_NAMESPACE::cpp::string_view;14using LIBC_NAMESPACE::cpp::to_string;15 16TEST(LlvmLibcStringTest, InitializeEmpty) {17 const string s;18 ASSERT_EQ(s.size(), size_t(0));19 ASSERT_TRUE(s.empty());20 ASSERT_STREQ(s.data(), "");21 ASSERT_STREQ(s.c_str(), "");22 ASSERT_EQ(s.data(), s.c_str());23 ASSERT_EQ(s.capacity(), size_t(0));24}25 26TEST(LlvmLibcStringTest, InitializeCString) {27 const char *const str = "abc";28 const string s(str);29 ASSERT_EQ(s.size(), size_t(3));30 ASSERT_FALSE(s.empty());31 ASSERT_NE(s.data(), &str[0]);32 ASSERT_EQ(s[0], 'a');33 ASSERT_EQ(s[1], 'b');34 ASSERT_EQ(s[2], 'c');35 ASSERT_EQ(s.front(), 'a');36 ASSERT_EQ(s.back(), 'c');37 ASSERT_EQ(s.data(), s.c_str());38}39 40TEST(LlvmLibcStringTest, ToCString) {41 const char *const str = "abc";42 string s(str);43 const char *cstr = s.c_str();44 ASSERT_EQ(s.size(), size_t(3));45 ASSERT_STREQ(str, cstr);46}47 48TEST(LlvmLibcStringTest, ToStringView) {49 const char *const str = "abc";50 string s(str);51 string_view view = s;52 ASSERT_EQ(view, string_view(str));53}54 55TEST(LlvmLibcStringTest, InitializeCStringWithSize) {56 const char *const str = "abc";57 const string s(str, 2);58 ASSERT_EQ(s.size(), size_t(2));59 ASSERT_EQ(s[0], 'a');60 ASSERT_EQ(s[1], 'b');61 ASSERT_EQ(s.front(), 'a');62 ASSERT_EQ(s.back(), 'b');63}64 65TEST(LlvmLibcStringTest, InitializeStringView) {66 const string_view str = "ab";67 const string s(str);68 ASSERT_EQ(s.size(), size_t(2));69 ASSERT_EQ(s[0], 'a');70 ASSERT_EQ(s[1], 'b');71 ASSERT_EQ(s.front(), 'a');72 ASSERT_EQ(s.back(), 'b');73}74 75TEST(LlvmLibcStringTest, InitializeRepeatedChar) {76 const string s(4, '1');77 ASSERT_EQ(string_view(s), string_view("1111"));78}79 80TEST(LlvmLibcStringTest, InitializeZeorChar) {81 const string s(0, '1');82 ASSERT_TRUE(s.empty());83}84 85TEST(LlvmLibcStringTest, CopyConstruct) {86 const char *const str = "abc";87 string a(str);88 string b(a);89 // Same content90 ASSERT_STREQ(a.c_str(), str);91 ASSERT_STREQ(b.c_str(), str);92 // Different pointers93 ASSERT_NE(a.data(), b.data());94}95 96string &&move(string &value) { return static_cast<string &&>(value); }97 98TEST(LlvmLibcStringTest, CopyAssign) {99 const char *const str = "abc";100 string a(str);101 string b;102 b = a;103 // Same content104 ASSERT_STREQ(a.c_str(), str);105 ASSERT_STREQ(b.c_str(), str);106 // Different pointers107 ASSERT_NE(a.data(), b.data());108}109 110TEST(LlvmLibcStringTest, MoveConstruct) {111 const char *const str = "abc";112 string a(str);113 string b(move(a));114 ASSERT_STREQ(b.c_str(), str);115 ASSERT_STREQ(a.c_str(), "");116}117 118TEST(LlvmLibcStringTest, MoveAssign) {119 const char *const str = "abc";120 string a(str);121 string b;122 b = move(a);123 ASSERT_STREQ(b.c_str(), str);124 ASSERT_STREQ(a.c_str(), "");125}126 127TEST(LlvmLibcStringTest, StringViewAssign) {128 const string_view str = "ab";129 string s;130 s = str;131 ASSERT_EQ(s.size(), size_t(2));132 ASSERT_EQ(s[0], 'a');133 ASSERT_EQ(s[1], 'b');134 ASSERT_EQ(s.front(), 'a');135 ASSERT_EQ(s.back(), 'b');136}137 138TEST(LlvmLibcStringTest, Concat) {139 const char *const str = "abc";140 string a(str);141 string b;142 b += a;143 ASSERT_STREQ(b.c_str(), "abc");144 b += a;145 ASSERT_STREQ(b.c_str(), "abcabc");146}147 148TEST(LlvmLibcStringTest, AddChar) {149 string a;150 a += 'a';151 ASSERT_STREQ(a.c_str(), "a");152 a += 'b';153 ASSERT_STREQ(a.c_str(), "ab");154}155 156TEST(LlvmLibcStringTest, ResizeCapacityAndNullTermination) {157 string a;158 // Empty159 ASSERT_EQ(a.capacity(), size_t(0));160 ASSERT_EQ(a.data()[0], '\0');161 // Still empty162 a.resize(0);163 ASSERT_EQ(a.capacity(), size_t(0));164 ASSERT_EQ(a.data()[0], '\0');165 // One char166 a.resize(1);167 ASSERT_EQ(a.size(), size_t(1));168 ASSERT_GE(a.capacity(), size_t(2));169 ASSERT_EQ(a.data()[1], '\0');170 // Clear171 a.resize(0);172 ASSERT_EQ(a.size(), size_t(0));173 ASSERT_GE(a.capacity(), size_t(2));174 ASSERT_EQ(a.data()[0], '\0');175 // Resize and check zero initialized176 a.resize(10);177 ASSERT_EQ(a.size(), size_t(10));178 ASSERT_GE(a.capacity(), size_t(10));179 for (size_t i = 0; i < 10; ++i)180 ASSERT_EQ(a[i], '\0');181}182 183TEST(LlvmLibcStringTest, ConcatWithCString) {184 ASSERT_STREQ((string("a") + string("b")).c_str(), "ab");185 ASSERT_STREQ((string("a") + "b").c_str(), "ab");186 ASSERT_STREQ(("a" + string("b")).c_str(), "ab");187}188 189TEST(LlvmLibcStringTest, Comparison) {190 // Here we simply check that comparison of string and string_view have the191 // same semantic.192 struct CStringPair {193 const char *const a;194 const char *const b;195 } kTestPairs[] = {{"a", "b"}, {"", "xyz"}};196 for (const auto [pa, pb] : kTestPairs) {197 const string sa(pa);198 const string sb(pb);199 const string_view sva(pa);200 const string_view svb(pb);201 ASSERT_EQ(sa == sb, sva == svb);202 ASSERT_EQ(sa != sb, sva != svb);203 ASSERT_EQ(sa >= sb, sva >= svb);204 ASSERT_EQ(sa <= sb, sva <= svb);205 ASSERT_EQ(sa < sb, sva < svb);206 ASSERT_EQ(sa > sb, sva > svb);207 }208}209 210TEST(LlvmLibcStringTest, ToString) {211 struct CStringPair {212 const int value;213 const string str;214 } kTestPairs[] = {{123, "123"}, {0, "0"}, {-321, "-321"}};215 for (const auto &[value, str] : kTestPairs) {216 ASSERT_EQ(to_string((int)(value)), str);217 ASSERT_EQ(to_string((long)(value)), str);218 ASSERT_EQ(to_string((long long)(value)), str);219 if (value >= 0) {220 ASSERT_EQ(to_string((unsigned int)(value)), str);221 ASSERT_EQ(to_string((unsigned long)(value)), str);222 ASSERT_EQ(to_string((unsigned long long)(value)), str);223 }224 }225}226