1 //===-- StringListTest.cpp ------------------------------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Utility/StringList.h" 10 #include "lldb/Utility/StreamString.h" 11 #include "gmock/gmock.h" 12 #include "gtest/gtest.h" 13 14 using namespace lldb_private; 15 16 TEST(StringListTest, DefaultConstructor) { 17 StringList s; 18 EXPECT_EQ(0U, s.GetSize()); 19 } 20 21 TEST(StringListTest, Assignment) { 22 StringList orig; 23 orig.AppendString("foo"); 24 orig.AppendString("bar"); 25 26 StringList s = orig; 27 28 ASSERT_EQ(2U, s.GetSize()); 29 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 30 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 31 32 ASSERT_EQ(2U, orig.GetSize()); 33 EXPECT_STREQ("foo", orig.GetStringAtIndex(0)); 34 EXPECT_STREQ("bar", orig.GetStringAtIndex(1)); 35 } 36 37 TEST(StringListTest, AppendStringStdString) { 38 StringList s; 39 s.AppendString("foo"); 40 ASSERT_EQ(1U, s.GetSize()); 41 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 42 43 s.AppendString("bar"); 44 ASSERT_EQ(2U, s.GetSize()); 45 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 46 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 47 } 48 49 TEST(StringListTest, AppendStringCString) { 50 StringList s; 51 s.AppendString("foo", strlen("foo")); 52 ASSERT_EQ(1U, s.GetSize()); 53 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 54 55 s.AppendString("bar", strlen("bar")); 56 ASSERT_EQ(2U, s.GetSize()); 57 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 58 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 59 } 60 61 TEST(StringListTest, AppendStringMove) { 62 StringList s; 63 std::string foo = "foo"; 64 std::string bar = "bar"; 65 66 s.AppendString(std::move(foo)); 67 ASSERT_EQ(1U, s.GetSize()); 68 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 69 70 s.AppendString(std::move(bar)); 71 ASSERT_EQ(2U, s.GetSize()); 72 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 73 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 74 } 75 76 TEST(StringListTest, ShiftStdString) { 77 StringList s; 78 std::string foo = "foo"; 79 std::string bar = "bar"; 80 81 s << foo; 82 ASSERT_EQ(1U, s.GetSize()); 83 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 84 85 s << bar; 86 ASSERT_EQ(2U, s.GetSize()); 87 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 88 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 89 } 90 91 TEST(StringListTest, ShiftCString) { 92 StringList s; 93 s << "foo"; 94 ASSERT_EQ(1U, s.GetSize()); 95 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 96 97 s << "bar"; 98 ASSERT_EQ(2U, s.GetSize()); 99 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 100 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 101 } 102 103 TEST(StringListTest, ShiftMove) { 104 StringList s; 105 std::string foo = "foo"; 106 std::string bar = "bar"; 107 108 s << std::move(foo); 109 ASSERT_EQ(1U, s.GetSize()); 110 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 111 112 s << std::move(bar); 113 ASSERT_EQ(2U, s.GetSize()); 114 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 115 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 116 } 117 118 TEST(StringListTest, AppendListCStringArrayEmpty) { 119 StringList s; 120 s.AppendList(nullptr, 0); 121 EXPECT_EQ(0U, s.GetSize()); 122 } 123 124 TEST(StringListTest, AppendListCStringArray) { 125 StringList s; 126 const char *items[3] = {"foo", "", "bar"}; 127 s.AppendList(items, 3); 128 129 EXPECT_EQ(3U, s.GetSize()); 130 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 131 EXPECT_STREQ("", s.GetStringAtIndex(1)); 132 EXPECT_STREQ("bar", s.GetStringAtIndex(2)); 133 } 134 135 TEST(StringListTest, AppendList) { 136 StringList other; 137 other.AppendString("foo"); 138 other.AppendString(""); 139 other.AppendString("bar"); 140 141 StringList empty; 142 143 StringList s; 144 s.AppendList(other); 145 146 EXPECT_EQ(3U, s.GetSize()); 147 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 148 EXPECT_STREQ("", s.GetStringAtIndex(1)); 149 EXPECT_STREQ("bar", s.GetStringAtIndex(2)); 150 151 EXPECT_EQ(3U, other.GetSize()); 152 EXPECT_STREQ("foo", other.GetStringAtIndex(0)); 153 EXPECT_STREQ("", other.GetStringAtIndex(1)); 154 EXPECT_STREQ("bar", other.GetStringAtIndex(2)); 155 156 s.AppendList(empty); 157 s.AppendList(other); 158 EXPECT_EQ(6U, s.GetSize()); 159 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 160 EXPECT_STREQ("", s.GetStringAtIndex(1)); 161 EXPECT_STREQ("bar", s.GetStringAtIndex(2)); 162 EXPECT_STREQ("foo", s.GetStringAtIndex(3)); 163 EXPECT_STREQ("", s.GetStringAtIndex(4)); 164 EXPECT_STREQ("bar", s.GetStringAtIndex(5)); 165 166 EXPECT_EQ(3U, other.GetSize()); 167 EXPECT_STREQ("foo", other.GetStringAtIndex(0)); 168 EXPECT_STREQ("", other.GetStringAtIndex(1)); 169 EXPECT_STREQ("bar", other.GetStringAtIndex(2)); 170 } 171 172 TEST(StringListTest, GetSize) { 173 StringList s; 174 s.AppendString("foo"); 175 EXPECT_EQ(1U, s.GetSize()); 176 177 s.AppendString("foo"); 178 EXPECT_EQ(2U, s.GetSize()); 179 180 s.AppendString("foobar"); 181 EXPECT_EQ(3U, s.GetSize()); 182 } 183 184 TEST(StringListTest, SetSize) { 185 StringList s; 186 s.SetSize(3); 187 EXPECT_EQ(3U, s.GetSize()); 188 EXPECT_STREQ("", s.GetStringAtIndex(0)); 189 EXPECT_STREQ("", s.GetStringAtIndex(1)); 190 EXPECT_STREQ("", s.GetStringAtIndex(2)); 191 } 192 193 TEST(StringListTest, SplitIntoLines) { 194 StringList s; 195 s.SplitIntoLines("\nfoo\nbar\n\n"); 196 EXPECT_EQ(4U, s.GetSize()); 197 EXPECT_STREQ("", s.GetStringAtIndex(0)); 198 EXPECT_STREQ("foo", s.GetStringAtIndex(1)); 199 EXPECT_STREQ("bar", s.GetStringAtIndex(2)); 200 EXPECT_STREQ("", s.GetStringAtIndex(3)); 201 } 202 203 TEST(StringListTest, SplitIntoLinesSingleTrailingCR) { 204 StringList s; 205 s.SplitIntoLines("\r"); 206 EXPECT_EQ(1U, s.GetSize()); 207 EXPECT_STREQ("", s.GetStringAtIndex(0)); 208 } 209 210 TEST(StringListTest, SplitIntoLinesEmpty) { 211 StringList s; 212 s.SplitIntoLines(""); 213 EXPECT_EQ(0U, s.GetSize()); 214 } 215 216 TEST(StringListTest, LongestCommonPrefixEmpty) { 217 StringList s; 218 std::string prefix = s.LongestCommonPrefix(); 219 EXPECT_EQ("", prefix); 220 } 221 222 TEST(StringListTest, LongestCommonPrefix) { 223 StringList s; 224 s.AppendString("foo"); 225 s.AppendString("foobar"); 226 s.AppendString("foo"); 227 s.AppendString("foozar"); 228 229 std::string prefix = s.LongestCommonPrefix(); 230 EXPECT_EQ("foo", prefix); 231 } 232 233 TEST(StringListTest, LongestCommonPrefixSingleElement) { 234 StringList s; 235 s.AppendString("foo"); 236 237 std::string prefix = s.LongestCommonPrefix(); 238 EXPECT_EQ("foo", prefix); 239 } 240 241 TEST(StringListTest, LongestCommonPrefixDuplicateElement) { 242 StringList s; 243 s.AppendString("foo"); 244 s.AppendString("foo"); 245 246 std::string prefix = s.LongestCommonPrefix(); 247 EXPECT_EQ("foo", prefix); 248 } 249 250 TEST(StringListTest, LongestCommonPrefixNoPrefix) { 251 StringList s; 252 s.AppendString("foo"); 253 s.AppendString("1foobar"); 254 s.AppendString("2foo"); 255 s.AppendString("3foozar"); 256 257 std::string prefix = s.LongestCommonPrefix(); 258 EXPECT_EQ("", prefix); 259 } 260 261 TEST(StringListTest, Clear) { 262 StringList s; 263 s.Clear(); 264 EXPECT_EQ(0U, s.GetSize()); 265 266 s.AppendString("foo"); 267 s.Clear(); 268 EXPECT_EQ(0U, s.GetSize()); 269 270 s.AppendString("foo"); 271 s.AppendString("foo"); 272 s.Clear(); 273 EXPECT_EQ(0U, s.GetSize()); 274 } 275 276 TEST(StringListTest, PopBack) { 277 StringList s; 278 s.AppendString("foo"); 279 s.AppendString("bar"); 280 s.AppendString("boo"); 281 282 s.PopBack(); 283 EXPECT_EQ(2U, s.GetSize()); 284 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 285 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 286 287 s.PopBack(); 288 EXPECT_EQ(1U, s.GetSize()); 289 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 290 291 s.PopBack(); 292 EXPECT_EQ(0U, s.GetSize()); 293 } 294 295 TEST(StringListTest, RemoveBlankLines) { 296 StringList s; 297 298 // Nothing to remove yet. 299 s.RemoveBlankLines(); 300 EXPECT_EQ(0U, s.GetSize()); 301 302 // Add some lines. 303 s.AppendString(""); 304 s.AppendString(""); 305 s.AppendString("\t"); 306 s.AppendString(""); 307 s.AppendString(" "); 308 s.AppendString(""); 309 s.AppendString(""); 310 s.AppendString("f"); 311 s.AppendString(""); 312 s.AppendString(""); 313 314 // And remove all the empty ones again. 315 s.RemoveBlankLines(); 316 317 EXPECT_EQ(3U, s.GetSize()); 318 EXPECT_STREQ("\t", s.GetStringAtIndex(0)); 319 EXPECT_STREQ(" ", s.GetStringAtIndex(1)); 320 EXPECT_STREQ("f", s.GetStringAtIndex(2)); 321 } 322 323 TEST(StringListTest, InsertStringAtIndexStart) { 324 StringList s; 325 326 s.InsertStringAtIndex(0, "bar"); 327 EXPECT_EQ(1U, s.GetSize()); 328 EXPECT_STREQ("bar", s.GetStringAtIndex(0)); 329 330 s.InsertStringAtIndex(0, "foo"); 331 EXPECT_EQ(2U, s.GetSize()); 332 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 333 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 334 } 335 336 TEST(StringListTest, InsertStringAtIndexEnd) { 337 StringList s; 338 339 s.InsertStringAtIndex(0, "foo"); 340 EXPECT_EQ(1U, s.GetSize()); 341 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 342 343 s.InsertStringAtIndex(1, "bar"); 344 EXPECT_EQ(2U, s.GetSize()); 345 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 346 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 347 } 348 349 TEST(StringListTest, InsertStringAtIndexOutOfBounds) { 350 StringList s; 351 352 s.InsertStringAtIndex(1, "foo"); 353 EXPECT_EQ(1U, s.GetSize()); 354 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 355 356 // FIXME: Inserting at an OOB index will always just append to the list. This 357 // seems not very intuitive. 358 s.InsertStringAtIndex(3, "bar"); 359 EXPECT_EQ(2U, s.GetSize()); 360 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 361 EXPECT_STREQ("bar", s.GetStringAtIndex(1)); 362 } 363 364 TEST(StringListTest, InsertStringAtIndexStdString) { 365 StringList s; 366 367 std::string foo = "foo"; 368 s.InsertStringAtIndex(0, foo); 369 EXPECT_EQ(1U, s.GetSize()); 370 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 371 } 372 373 TEST(StringListTest, InsertStringAtIndexMove) { 374 StringList s; 375 376 std::string foo = "foo"; 377 s.InsertStringAtIndex(0, std::move(foo)); 378 EXPECT_EQ(1U, s.GetSize()); 379 EXPECT_STREQ("foo", s.GetStringAtIndex(0)); 380 } 381 382 TEST(StringListTest, CopyListEmpty) { 383 StringList s; 384 385 EXPECT_EQ("", s.CopyList()); 386 EXPECT_EQ("", s.CopyList("+")); 387 } 388 389 TEST(StringListTest, CopyListSingle) { 390 StringList s; 391 s.AppendString("ab"); 392 393 EXPECT_EQ("ab", s.CopyList()); 394 EXPECT_EQ("-ab", s.CopyList("-")); 395 } 396 397 TEST(StringListTest, CopyList) { 398 StringList s; 399 s.AppendString("ab"); 400 s.AppendString("cd"); 401 402 EXPECT_EQ("ab\ncd", s.CopyList()); 403 EXPECT_EQ("-ab\n-cd", s.CopyList("-")); 404 } 405 406 TEST(StringListTest, Join) { 407 StringList s; 408 s.AppendString("ab"); 409 s.AppendString("cd"); 410 411 StreamString ss; 412 s.Join(" ", ss); 413 414 EXPECT_EQ("ab cd", ss.GetString()); 415 } 416 417 TEST(StringListTest, JoinEmpty) { 418 StringList s; 419 420 StreamString ss; 421 s.Join(" ", ss); 422 423 EXPECT_EQ("", ss.GetString()); 424 } 425 426 TEST(StringListTest, JoinSingle) { 427 StringList s; 428 s.AppendString("foo"); 429 430 StreamString ss; 431 s.Join(" ", ss); 432 433 EXPECT_EQ("foo", ss.GetString()); 434 } 435 436 TEST(StringListTest, JoinThree) { 437 StringList s; 438 s.AppendString("1"); 439 s.AppendString("2"); 440 s.AppendString("3"); 441 442 StreamString ss; 443 s.Join(" ", ss); 444 445 EXPECT_EQ("1 2 3", ss.GetString()); 446 } 447 448 TEST(StringListTest, JoinNonSpace) { 449 StringList s; 450 s.AppendString("1"); 451 s.AppendString("2"); 452 s.AppendString("3"); 453 454 StreamString ss; 455 s.Join(".", ss); 456 457 EXPECT_EQ("1.2.3", ss.GetString()); 458 } 459 460 TEST(StringListTest, JoinMultiCharSeparator) { 461 StringList s; 462 s.AppendString("1"); 463 s.AppendString("2"); 464 s.AppendString("3"); 465 466 StreamString ss; 467 s.Join("--", ss); 468 469 EXPECT_EQ("1--2--3", ss.GetString()); 470 } 471 472 TEST(StringListTest, GetMaxStringLengthEqualSize) { 473 StringList s; 474 s.AppendString("123"); 475 s.AppendString("123"); 476 EXPECT_EQ(3U, s.GetMaxStringLength()); 477 } 478 479 TEST(StringListTest, GetMaxStringLengthIncreasingSize) { 480 StringList s; 481 s.AppendString("123"); 482 s.AppendString("1234"); 483 EXPECT_EQ(4U, s.GetMaxStringLength()); 484 } 485 486 TEST(StringListTest, GetMaxStringLengthDecreasingSize) { 487 StringList s; 488 s.AppendString("1234"); 489 s.AppendString("123"); 490 EXPECT_EQ(4U, s.GetMaxStringLength()); 491 } 492 493 TEST(StringListTest, GetMaxStringLengthMixed) { 494 StringList s; 495 s.AppendString("123"); 496 s.AppendString("1"); 497 s.AppendString("123"); 498 s.AppendString("1234"); 499 s.AppendString("123"); 500 s.AppendString("1"); 501 EXPECT_EQ(4U, s.GetMaxStringLength()); 502 } 503 504 TEST(StringListTest, GetMaxStringLengthEmpty) { 505 StringList s; 506 EXPECT_EQ(0U, s.GetMaxStringLength()); 507 } 508 509 TEST(StringListTest, ForRangeEmpty) { 510 StringList s; 511 for (const std::string &e : s) 512 FAIL() << "Shouldn't have hit an element in for range" << e; 513 } 514 515 TEST(StringListTest, ForRange) { 516 StringList s; 517 s.AppendString("a"); 518 s.AppendString("b"); 519 s.AppendString("c"); 520 std::vector<std::string> recorded; 521 for (const std::string &e : s) 522 recorded.push_back(e); 523 EXPECT_THAT(recorded, testing::ElementsAre("a", "b", "c")); 524 } 525