1 // Copyright 2014 The Android Open Source Project 2 // 3 // This software is licensed under the terms of the GNU General Public 4 // License version 2, as published by the Free Software Foundation, and 5 // may be copied, distributed, and modified under those terms. 6 // 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 12 #include "android/base/String.h" 13 14 #include "android/base/StringView.h" 15 16 #include <gtest/gtest.h> 17 18 namespace android { 19 namespace base { 20 21 TEST(String, DefaultConstructor) { 22 String s; 23 EXPECT_EQ(0U, s.size()); 24 EXPECT_TRUE(s.empty()); 25 } 26 27 TEST(String, SimpleConstructor) { 28 static const char kString[] = "hello you"; 29 const size_t kStringLen = sizeof(kString) - 1U; 30 31 String s(kString); 32 EXPECT_NE(kString, s.c_str()); 33 EXPECT_EQ(kStringLen, s.size()); 34 EXPECT_FALSE(s.empty()); 35 EXPECT_STREQ(kString, s.c_str()); 36 } 37 38 TEST(String, SimpleConstructorWithLongString) { 39 static const char kString[] = 40 "this is a long string that should exceed the " 41 "small-string-optimization capacity"; 42 const size_t kStringLen = sizeof(kString) - 1U; 43 44 String s(kString); 45 EXPECT_NE(kString, s.c_str()); 46 EXPECT_EQ(kStringLen, s.size()); 47 EXPECT_FALSE(s.empty()); 48 EXPECT_STREQ(kString, s.c_str()); 49 } 50 51 TEST(String, CopyConstructor) { 52 String s1("Hello World!"); 53 String s2(s1); 54 EXPECT_EQ(s1.size(), s2.size()); 55 EXPECT_STREQ(s1.c_str(), s2.c_str()); 56 } 57 58 TEST(String, ConstructorFromStringView) { 59 StringView view("Hello Cowboys"); 60 String s(view); 61 EXPECT_NE(view.str(), s.c_str()); 62 EXPECT_EQ(view.size(), s.size()); 63 EXPECT_STREQ(view.str(), s.c_str()); 64 } 65 66 TEST(String, ConstructorWithCountAndFill) { 67 const size_t kCount = 1024; 68 const char kFill = 0x42; 69 70 String s(kCount, kFill); 71 EXPECT_EQ(kCount, s.size()); 72 for (size_t n = 0; n < kCount; ++n) 73 EXPECT_EQ(kFill, s[n]); 74 } 75 76 TEST(String, empty) { 77 String s1(""); 78 EXPECT_TRUE(s1.empty()); 79 80 String s2("foo"); 81 EXPECT_FALSE(s2.empty()); 82 } 83 84 TEST(String, size) { 85 const size_t kCount = 4096; 86 String s; 87 for (size_t n = 0; n < kCount; ++n) { 88 EXPECT_EQ(n, s.size()); 89 s += 'x'; 90 } 91 EXPECT_EQ(kCount, s.size()); 92 } 93 94 TEST(String, clear) { 95 String s("foo bar"); 96 EXPECT_FALSE(s.empty()); 97 s.clear(); 98 EXPECT_TRUE(s.empty()); 99 EXPECT_EQ(0U, s.size()); 100 } 101 102 TEST(String, IndexedAccess) { 103 String s("foobar"); 104 EXPECT_EQ('f', s[0]); 105 EXPECT_EQ('o', s[1]); 106 EXPECT_EQ('o', s[2]); 107 EXPECT_EQ('b', s[3]); 108 EXPECT_EQ('a', s[4]); 109 EXPECT_EQ('r', s[5]); 110 EXPECT_EQ('\0', s[6]); 111 } 112 113 TEST(String, AssignOperatorWithCString) { 114 static const char kString[] = "Hello 10234"; 115 const size_t kStringLen = sizeof(kString) - 1U; 116 117 String s; 118 s = kString; 119 EXPECT_NE(kString, s.c_str()); 120 EXPECT_EQ(kStringLen, s.size()); 121 EXPECT_STREQ(kString, s.c_str()); 122 } 123 124 TEST(String, AssignOperatorWithOtherString) { 125 String s0("A fish named Wanda"); 126 String s; 127 s = s0; 128 EXPECT_EQ(s0.size(), s.size()); 129 EXPECT_STREQ(s0.c_str(), s.c_str()); 130 } 131 132 TEST(String, AssignOperatorWithStringView) { 133 StringView v0("What a beautiful world"); 134 String s; 135 s = v0; 136 EXPECT_EQ(v0.size(), s.size()); 137 EXPECT_STREQ(v0.str(), s.c_str()); 138 } 139 140 TEST(String, AssignOperatorWithChar) { 141 String s; 142 s = 'f'; 143 EXPECT_EQ(1U, s.size()); 144 EXPECT_EQ('f', s[0]); 145 } 146 147 TEST(String, assignWithCString) { 148 static const char kString[] = "Hello"; 149 const size_t kStringLen = sizeof(kString) - 1U; 150 151 String s; 152 s.assign(kString); 153 EXPECT_EQ(kStringLen, s.size()); 154 EXPECT_STREQ(kString, s.c_str()); 155 } 156 157 TEST(String, assignWithString) { 158 String s0("Input string"); 159 String s; 160 s.assign(s0); 161 EXPECT_EQ(s0.size(), s.size()); 162 EXPECT_STREQ(s0.c_str(), s.c_str()); 163 } 164 165 TEST(String, assignWithStringAndLen) { 166 static const char kString[] = "Who you're gonna call?"; 167 const size_t kStringLen = sizeof(kString) - 1U; 168 169 String s; 170 s.assign(kString, kStringLen); 171 EXPECT_NE(kString, s.c_str()); 172 EXPECT_EQ(kStringLen, s.size()); 173 EXPECT_STREQ(kString, s.c_str()); 174 } 175 176 TEST(String, assignWithCountAndFill) { 177 const size_t kCount = 1024; 178 const char kFill = '\x7f'; 179 String s; 180 s.assign(kCount, kFill); 181 EXPECT_EQ(kCount, s.size()); 182 for (size_t n = 0; n < kCount; ++n) { 183 EXPECT_EQ(kFill, s[n]) << "At index " << n; 184 } 185 } 186 187 TEST(String, assignWithStringView) { 188 StringView v0("Input string view"); 189 String s; 190 s.assign(v0); 191 EXPECT_EQ(v0.size(), s.size()); 192 EXPECT_STREQ(v0.str(), s.c_str()); 193 } 194 195 TEST(String, assignWithChar) { 196 String s; 197 s.assign('f'); 198 EXPECT_EQ(1U, s.size()); 199 EXPECT_STREQ("f", s.c_str()); 200 } 201 202 typedef struct { 203 const char* s1; 204 const char* s2; 205 int expected; 206 } Comparison; 207 208 static const Comparison kComparisons[] = { 209 { "", "", 0 }, 210 { "", "foo", -1 }, 211 { "foo", "", +1 }, 212 { "foo", "zoo", -1 }, 213 { "foo", "foo", 0 }, 214 { "foo", "fo", +1 }, 215 { "foo", "fooo", -1 }, 216 { "foo", "fop", -1 }, 217 { "foo", "fon", +1 }, 218 }; 219 220 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 221 222 TEST(String, compareWithCString) { 223 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 224 const Comparison& comp = kComparisons[n]; 225 String s(comp.s1); 226 EXPECT_EQ(comp.expected, s.compare(comp.s2)) 227 << "Comparing '" << comp.s1 << "' with '" 228 << comp.s2 << "'"; 229 } 230 } 231 232 TEST(String, compareWithCStringWithLen) { 233 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 234 const Comparison& comp = kComparisons[n]; 235 String s(comp.s1); 236 size_t len2 = ::strlen(comp.s2); 237 EXPECT_EQ(comp.expected, s.compare(comp.s2, len2)) 238 << "Comparing '" << comp.s1 << "' with '" 239 << comp.s2 << "'"; 240 } 241 } 242 243 244 TEST(String, compareWithString) { 245 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 246 const Comparison& comp = kComparisons[n]; 247 String s1(comp.s1); 248 String s2(comp.s2); 249 EXPECT_EQ(comp.expected, s1.compare(s2)) 250 << "Comparing '" << comp.s1 << "' with '" 251 << comp.s2 << "'"; 252 } 253 } 254 255 TEST(String, compareWithStringView) { 256 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 257 const Comparison& comp = kComparisons[n]; 258 String s1(comp.s1); 259 StringView s2(comp.s2); 260 EXPECT_EQ(comp.expected, s1.compare(s2)) 261 << "Comparing '" << comp.s1 << "' with '" 262 << comp.s2 << "'"; 263 } 264 } 265 266 TEST(String, equalsWithCString) { 267 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 268 const Comparison& comp = kComparisons[n]; 269 String s(comp.s1); 270 EXPECT_EQ(!comp.expected, s.equals(comp.s2)) 271 << "Comparing '" << comp.s1 << "' with '" 272 << comp.s2 << "'"; 273 } 274 } 275 276 TEST(String, equalsWithCStringWithLen) { 277 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 278 const Comparison& comp = kComparisons[n]; 279 String s(comp.s1); 280 size_t len2 = ::strlen(comp.s2); 281 EXPECT_EQ(!comp.expected, s.equals(comp.s2, len2)) 282 << "Comparing '" << comp.s1 << "' with '" 283 << comp.s2 << "'"; 284 } 285 } 286 287 288 TEST(String, equalsWithString) { 289 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 290 const Comparison& comp = kComparisons[n]; 291 String s1(comp.s1); 292 String s2(comp.s2); 293 EXPECT_EQ(!comp.expected, s1.equals(s2)) 294 << "Comparing '" << comp.s1 << "' with '" 295 << comp.s2 << "'"; 296 } 297 } 298 299 TEST(String, equalsWithStringView) { 300 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 301 const Comparison& comp = kComparisons[n]; 302 String s1(comp.s1); 303 StringView s2(comp.s2); 304 EXPECT_EQ(!comp.expected, s1.equals(s2)) 305 << "Comparing '" << comp.s1 << "' with '" 306 << comp.s2 << "'"; 307 } 308 } 309 310 TEST(String, EqualsOperatorWithCString) { 311 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 312 const Comparison& comp = kComparisons[n]; 313 String s(comp.s1); 314 EXPECT_EQ(!comp.expected, s == comp.s2) 315 << "Comparing '" << comp.s1 << "' with '" 316 << comp.s2 << "'"; 317 } 318 } 319 320 TEST(String, EqualsOperatorWithString) { 321 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 322 const Comparison& comp = kComparisons[n]; 323 String s1(comp.s1); 324 String s2(comp.s2); 325 EXPECT_EQ(!comp.expected, s1 == s2) 326 << "Comparing '" << comp.s1 << "' with '" 327 << comp.s2 << "'"; 328 } 329 } 330 331 TEST(String, EqualsOperatorWithStringView) { 332 for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) { 333 const Comparison& comp = kComparisons[n]; 334 String s1(comp.s1); 335 StringView s2(comp.s2); 336 EXPECT_EQ(!comp.expected, s1 == s2) 337 << "Comparing '" << comp.s1 << "' with '" 338 << comp.s2 << "'"; 339 } 340 } 341 342 TEST(String, Reserve0OnEmptyString) { 343 String s; 344 // This is really to check that this doesn't crash. 345 ::memset(&s, 0, sizeof(s)); 346 s.reserve(0U); 347 } 348 349 TEST(String, Swap) { 350 const String kShortString1("Hello World!"); 351 const String kLongString1("A very long string that will likely " 352 "exceed the small string optimization storage buffer"); 353 const String kShortString2("Menthe a l'eau"); 354 const String kLongString2("Harold Ramis, Chicago actor, writer " 355 "and director, dead at 69"); 356 357 // Swap two short strings. 358 { 359 String sa = kShortString1; 360 String sb = kShortString2; 361 sa.swap(&sb); 362 EXPECT_EQ(kShortString2, sa); 363 EXPECT_EQ(kShortString1, sb); 364 } 365 366 // Swap one short + one long string. 367 { 368 String sa = kShortString1; 369 String sb = kLongString1; 370 sa.swap(&sb); 371 EXPECT_EQ(kLongString1, sa); 372 EXPECT_EQ(kShortString1, sb); 373 } 374 375 // Swap one long + one short string. 376 { 377 String sa = kLongString1; 378 String sb = kLongString2; 379 sa.swap(&sb); 380 EXPECT_EQ(kLongString2, sa); 381 EXPECT_EQ(kLongString1, sb); 382 } 383 } 384 385 } // namespace base 386 } // namespace android 387