1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <utils/String16.h>
18 #include <utils/String8.h>
19 #include <compare>
20 #include <utility>
21
22 #include <gtest/gtest.h>
23
24 using namespace android;
25
Char16_tStringEquals(const char16_t * a,const char16_t * b)26 ::testing::AssertionResult Char16_tStringEquals(const char16_t* a, const char16_t* b) {
27 if (strcmp16(a, b) != 0) {
28 return ::testing::AssertionFailure()
29 << "\"" << String8(a).c_str() << "\" not equal to \"" << String8(b).c_str() << "\"";
30 }
31 return ::testing::AssertionSuccess();
32 }
33
34 #define EXPECT_STR16EQ(a, b) EXPECT_TRUE(Char16_tStringEquals(a, b))
35
TEST(String16Test,FromChar16_t)36 TEST(String16Test, FromChar16_t) {
37 String16 tmp(u"Verify me");
38 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
39 }
40
TEST(String16Test,FromChar16_tSized)41 TEST(String16Test, FromChar16_tSized) {
42 String16 tmp(u"Verify me", 7);
43 EXPECT_STR16EQ(u"Verify ", tmp.c_str());
44 }
45
TEST(String16Test,FromChar)46 TEST(String16Test, FromChar) {
47 String16 tmp("Verify me");
48 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
49 }
50
TEST(String16Test,FromCharSized)51 TEST(String16Test, FromCharSized) {
52 String16 tmp("Verify me", 7);
53 EXPECT_STR16EQ(u"Verify ", tmp.c_str());
54 }
55
TEST(String16Test,Copy)56 TEST(String16Test, Copy) {
57 String16 tmp("Verify me");
58 String16 another = tmp;
59 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
60 EXPECT_STR16EQ(u"Verify me", another.c_str());
61 }
62
TEST(String16Test,CopyAssign)63 TEST(String16Test, CopyAssign) {
64 String16 tmp("Verify me");
65 String16 another;
66 another = tmp;
67 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
68 EXPECT_STR16EQ(u"Verify me", another.c_str());
69 }
70
TEST(String16Test,Move)71 TEST(String16Test, Move) {
72 String16 tmp("Verify me");
73 String16 another(std::move(tmp));
74 EXPECT_STR16EQ(u"Verify me", another.c_str());
75 }
76
TEST(String16Test,MoveAssign)77 TEST(String16Test, MoveAssign) {
78 String16 tmp("Verify me");
79 String16 another;
80 another = std::move(tmp);
81 EXPECT_STR16EQ(u"Verify me", another.c_str());
82 }
83
TEST(String16Test,Size)84 TEST(String16Test, Size) {
85 String16 tmp("Verify me");
86 EXPECT_EQ(9U, tmp.size());
87 }
88
TEST(String16Test,setTo)89 TEST(String16Test, setTo) {
90 String16 tmp("Verify me");
91 tmp.setTo(u"New content");
92 EXPECT_EQ(11U, tmp.size());
93 EXPECT_STR16EQ(u"New content", tmp.c_str());
94 }
95
TEST(String16Test,Append)96 TEST(String16Test, Append) {
97 String16 tmp("Verify me");
98 tmp.append(String16("Hello"));
99 EXPECT_EQ(14U, tmp.size());
100 EXPECT_STR16EQ(u"Verify meHello", tmp.c_str());
101 }
102
TEST(String16Test,Insert)103 TEST(String16Test, Insert) {
104 String16 tmp("Verify me");
105 tmp.insert(6, u"Insert");
106 EXPECT_EQ(15U, tmp.size());
107 EXPECT_STR16EQ(u"VerifyInsert me", tmp.c_str());
108 }
109
TEST(String16Test,ReplaceAll)110 TEST(String16Test, ReplaceAll) {
111 String16 tmp("Verify verify Verify");
112 tmp.replaceAll(u'r', u'!');
113 EXPECT_STR16EQ(u"Ve!ify ve!ify Ve!ify", tmp.c_str());
114 }
115
TEST(String16Test,Compare)116 TEST(String16Test, Compare) {
117 String16 tmp("Verify me");
118 EXPECT_EQ(String16(u"Verify me"), tmp);
119 }
120
TEST(String16Test,StaticString)121 TEST(String16Test, StaticString) {
122 String16 nonStaticString("NonStatic");
123 StaticString16 staticString(u"Static");
124
125 EXPECT_TRUE(staticString.isStaticString());
126 EXPECT_FALSE(nonStaticString.isStaticString());
127 }
128
TEST(String16Test,StaticStringCopy)129 TEST(String16Test, StaticStringCopy) {
130 StaticString16 tmp(u"Verify me");
131 String16 another = tmp;
132 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
133 EXPECT_STR16EQ(u"Verify me", another.c_str());
134 EXPECT_TRUE(tmp.isStaticString());
135 EXPECT_TRUE(another.isStaticString());
136 }
137
TEST(String16Test,StaticStringMove)138 TEST(String16Test, StaticStringMove) {
139 StaticString16 tmp(u"Verify me");
140 String16 another(std::move(tmp));
141 EXPECT_STR16EQ(u"Verify me", another.c_str());
142 EXPECT_TRUE(another.isStaticString());
143 }
144
TEST(String16Test,StaticStringSize)145 TEST(String16Test, StaticStringSize) {
146 StaticString16 tmp(u"Verify me");
147 EXPECT_EQ(9U, tmp.size());
148 }
149
TEST(String16Test,StaticStringSetTo)150 TEST(String16Test, StaticStringSetTo) {
151 StaticString16 tmp(u"Verify me");
152 tmp.setTo(u"New content");
153 EXPECT_EQ(11U, tmp.size());
154 EXPECT_STR16EQ(u"New content", tmp);
155 EXPECT_FALSE(tmp.isStaticString());
156 }
157
TEST(String16Test,StaticStringAppend)158 TEST(String16Test, StaticStringAppend) {
159 StaticString16 tmp(u"Verify me");
160 tmp.append(String16("Hello"));
161 EXPECT_EQ(14U, tmp.size());
162 EXPECT_STR16EQ(u"Verify meHello", tmp.c_str());
163 EXPECT_FALSE(tmp.isStaticString());
164 }
165
TEST(String16Test,StaticStringInsert)166 TEST(String16Test, StaticStringInsert) {
167 StaticString16 tmp(u"Verify me");
168 tmp.insert(6, u"Insert");
169 EXPECT_EQ(15U, tmp.size());
170 EXPECT_STR16EQ(u"VerifyInsert me", tmp.c_str());
171 EXPECT_FALSE(tmp.isStaticString());
172 }
173
TEST(String16Test,StaticStringReplaceAll)174 TEST(String16Test, StaticStringReplaceAll) {
175 StaticString16 tmp(u"Verify verify Verify");
176 tmp.replaceAll(u'r', u'!');
177 EXPECT_STR16EQ(u"Ve!ify ve!ify Ve!ify", tmp.c_str());
178 EXPECT_FALSE(tmp.isStaticString());
179 }
180
TEST(String16Test,StaticStringCompare)181 TEST(String16Test, StaticStringCompare) {
182 StaticString16 tmp(u"Verify me");
183 EXPECT_EQ(String16(u"Verify me"), tmp);
184 }
185
TEST(String16Test,StringSetToStaticString)186 TEST(String16Test, StringSetToStaticString) {
187 StaticString16 tmp(u"Verify me");
188 String16 another(u"nonstatic");
189 another = tmp;
190 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
191 EXPECT_STR16EQ(u"Verify me", another.c_str());
192 }
193
TEST(String16Test,StringCopyAssignFromStaticString)194 TEST(String16Test, StringCopyAssignFromStaticString) {
195 StaticString16 tmp(u"Verify me");
196 String16 another(u"nonstatic");
197 another = tmp;
198 EXPECT_STR16EQ(u"Verify me", another.c_str());
199 EXPECT_TRUE(another.isStaticString());
200 EXPECT_STR16EQ(u"Verify me", tmp.c_str());
201 EXPECT_TRUE(tmp.isStaticString());
202 }
203
TEST(String16Test,StringMoveAssignFromStaticString)204 TEST(String16Test, StringMoveAssignFromStaticString) {
205 StaticString16 tmp(u"Verify me");
206 String16 another(u"nonstatic");
207 another = std::move(tmp);
208 EXPECT_STR16EQ(u"Verify me", another.c_str());
209 EXPECT_TRUE(another.isStaticString());
210 }
211
TEST(String16Test,EmptyStringIsStatic)212 TEST(String16Test, EmptyStringIsStatic) {
213 String16 tmp("");
214 EXPECT_TRUE(tmp.isStaticString());
215 }
216
TEST(String16Test,OverreadUtf8Conversion)217 TEST(String16Test, OverreadUtf8Conversion) {
218 char tmp[] = {'a', static_cast<char>(0xe0), '\0'};
219 String16 another(tmp);
220 EXPECT_TRUE(another.size() == 0);
221 }
222
TEST(String16Test,ValidUtf8Conversion)223 TEST(String16Test, ValidUtf8Conversion) {
224 String16 another("abcdef");
225 EXPECT_EQ(6U, another.size());
226 EXPECT_STR16EQ(another.c_str(), u"abcdef");
227 }
228
TEST(String16Test,append)229 TEST(String16Test, append) {
230 String16 s;
231 EXPECT_EQ(OK, s.append(String16(u"foo")));
232 EXPECT_STR16EQ(u"foo", s.c_str());
233 EXPECT_EQ(OK, s.append(String16(u"bar")));
234 EXPECT_STR16EQ(u"foobar", s.c_str());
235 EXPECT_EQ(OK, s.append(u"baz", 0));
236 EXPECT_STR16EQ(u"foobar", s.c_str());
237 EXPECT_EQ(NO_MEMORY, s.append(u"baz", SIZE_MAX));
238 EXPECT_STR16EQ(u"foobar", s.c_str());
239 }
240
TEST(String16Test,insert)241 TEST(String16Test, insert) {
242 String16 s;
243
244 // Inserting into the empty string inserts at the start.
245 EXPECT_EQ(OK, s.insert(123, u"foo"));
246 EXPECT_STR16EQ(u"foo", s.c_str());
247
248 // Inserting zero characters at any position is okay, but won't expand the string.
249 EXPECT_EQ(OK, s.insert(123, u"foo", 0));
250 EXPECT_STR16EQ(u"foo", s.c_str());
251
252 // Inserting past the end of a non-empty string appends.
253 EXPECT_EQ(OK, s.insert(123, u"bar"));
254 EXPECT_STR16EQ(u"foobar", s.c_str());
255
256 EXPECT_EQ(OK, s.insert(3, u"!"));
257 EXPECT_STR16EQ(u"foo!bar", s.c_str());
258
259 EXPECT_EQ(NO_MEMORY, s.insert(3, u"", SIZE_MAX));
260 EXPECT_STR16EQ(u"foo!bar", s.c_str());
261 }
262
TEST(String16Test,comparisons)263 TEST(String16Test, comparisons) {
264 const char16_t* cstr1 = u"abc";
265 const char16_t* cstr2 = u"def";
266
267 // str1 and str1b will point to different blocks of memory but with equal contents.
268 String16 str1(cstr1);
269 String16 str1b(cstr1);
270 String16 str2(cstr2);
271
272 EXPECT_TRUE((str1 <=> str1b) == 0);
273 EXPECT_FALSE(str1 != str1b);
274 EXPECT_FALSE(str1 < str1b);
275 EXPECT_TRUE(str1 <= str1b);
276 EXPECT_TRUE(str1 == str1b);
277 EXPECT_TRUE(str1 >= str1b);
278 EXPECT_FALSE(str1 > str1b);
279
280 EXPECT_TRUE((str1 <=> str2) < 0);
281 EXPECT_TRUE((str2 <=> str1) > 0);
282 EXPECT_TRUE(str1 != str2);
283 EXPECT_TRUE(str1 < str2);
284 EXPECT_TRUE(str1 <= str2);
285 EXPECT_FALSE(str1 == str2);
286 EXPECT_FALSE(str1 >= str2);
287 EXPECT_FALSE(str1 > str2);
288
289 // Verify that pre-C++20 comparison operators work with a std::pair of a String8, which only
290 // provides <=> in C++20 and up. See b/339775405.
291
292 std::pair<String16, int> pair1(str1, 13);
293 std::pair<String16, int> pair1b(str1b, 13);
294 std::pair<String16, int> pair2(str2, 13);
295
296 EXPECT_TRUE(pair1 == pair1b);
297 EXPECT_FALSE(pair1 < pair1b);
298 EXPECT_FALSE(pair1 > pair1b);
299
300 EXPECT_TRUE(pair1 != pair2);
301 EXPECT_TRUE(pair1 < pair2);
302 EXPECT_FALSE(pair1 > pair2);
303 }
304