1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "core/fxcrt/widestring.h" 6 7 #include <algorithm> 8 #include <vector> 9 10 #include "core/fxcrt/fx_string.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace fxcrt { 14 15 TEST(WideString, ElementAccess) { 16 const WideString abc(L"abc"); 17 EXPECT_EQ(L'a', abc[0]); 18 EXPECT_EQ(L'b', abc[1]); 19 EXPECT_EQ(L'c', abc[2]); 20 #ifndef NDEBUG 21 EXPECT_DEATH({ abc[4]; }, ".*"); 22 #endif 23 24 WideString mutable_abc = abc; 25 EXPECT_EQ(abc.c_str(), mutable_abc.c_str()); 26 EXPECT_EQ(L'a', mutable_abc[0]); 27 EXPECT_EQ(L'b', mutable_abc[1]); 28 EXPECT_EQ(L'c', mutable_abc[2]); 29 EXPECT_EQ(abc.c_str(), mutable_abc.c_str()); 30 EXPECT_EQ(L"abc", abc); 31 32 const wchar_t* c_str = abc.c_str(); 33 mutable_abc.SetAt(0, L'd'); 34 EXPECT_EQ(c_str, abc.c_str()); 35 EXPECT_NE(c_str, mutable_abc.c_str()); 36 EXPECT_EQ(L"abc", abc); 37 EXPECT_EQ(L"dbc", mutable_abc); 38 39 mutable_abc.SetAt(1, L'e'); 40 EXPECT_EQ(L"abc", abc); 41 EXPECT_EQ(L"dec", mutable_abc); 42 43 mutable_abc.SetAt(2, L'f'); 44 EXPECT_EQ(L"abc", abc); 45 EXPECT_EQ(L"def", mutable_abc); 46 #ifndef NDEBUG 47 EXPECT_DEATH({ mutable_abc.SetAt(3, L'g'); }, ".*"); 48 EXPECT_EQ(L"abc", abc); 49 #endif 50 } 51 52 TEST(WideString, OperatorLT) { 53 WideString empty; 54 WideString a(L"a"); 55 WideString abc(L"\x0110qq"); // Comes before despite endianness. 56 WideString def(L"\x1001qq"); // Comes after despite endianness. 57 WideStringView v_empty; 58 WideStringView v_a(L"a"); 59 WideStringView v_abc(L"\x0110qq"); 60 WideStringView v_def(L"\x1001qq"); 61 const wchar_t* const c_null = nullptr; 62 const wchar_t* const c_empty = L""; 63 const wchar_t* const c_a = L"a"; 64 const wchar_t* const c_abc = L"\x0110qq"; 65 const wchar_t* const c_def = L"\x1001qq"; 66 67 EXPECT_FALSE(empty < empty); 68 EXPECT_FALSE(a < a); 69 EXPECT_FALSE(abc < abc); 70 EXPECT_FALSE(def < def); 71 EXPECT_FALSE(c_null < empty); 72 EXPECT_FALSE(c_empty < empty); 73 EXPECT_FALSE(c_a < a); 74 EXPECT_FALSE(c_abc < abc); 75 EXPECT_FALSE(c_def < def); 76 EXPECT_FALSE(empty < c_null); 77 EXPECT_FALSE(empty < c_empty); 78 EXPECT_FALSE(a < c_a); 79 EXPECT_FALSE(abc < c_abc); 80 EXPECT_FALSE(def < c_def); 81 EXPECT_FALSE(empty < v_empty); 82 EXPECT_FALSE(a < v_a); 83 EXPECT_FALSE(abc < v_abc); 84 EXPECT_FALSE(def < v_def); 85 86 EXPECT_TRUE(empty < a); 87 EXPECT_FALSE(a < empty); 88 EXPECT_TRUE(c_null < a); 89 EXPECT_TRUE(c_empty < a); 90 EXPECT_FALSE(c_a < empty); 91 EXPECT_TRUE(empty < c_a); 92 EXPECT_FALSE(a < c_null); 93 EXPECT_FALSE(a < c_empty); 94 EXPECT_TRUE(empty < v_a); 95 EXPECT_FALSE(a < v_empty); 96 97 EXPECT_TRUE(empty < abc); 98 EXPECT_FALSE(abc < empty); 99 EXPECT_TRUE(c_null < abc); 100 EXPECT_TRUE(c_empty < abc); 101 EXPECT_FALSE(c_abc < empty); 102 EXPECT_TRUE(empty < c_abc); 103 EXPECT_FALSE(abc < c_null); 104 EXPECT_FALSE(abc < c_empty); 105 EXPECT_TRUE(empty < v_abc); 106 EXPECT_FALSE(abc < v_empty); 107 108 EXPECT_TRUE(empty < def); 109 EXPECT_FALSE(def < empty); 110 EXPECT_TRUE(c_null < def); 111 EXPECT_TRUE(c_empty < def); 112 EXPECT_FALSE(c_def < empty); 113 EXPECT_TRUE(empty < c_def); 114 EXPECT_FALSE(def < c_null); 115 EXPECT_FALSE(def < c_empty); 116 EXPECT_TRUE(empty < v_def); 117 EXPECT_FALSE(def < v_empty); 118 119 EXPECT_TRUE(a < abc); 120 EXPECT_FALSE(abc < a); 121 EXPECT_TRUE(c_a < abc); 122 EXPECT_FALSE(c_abc < a); 123 EXPECT_TRUE(a < c_abc); 124 EXPECT_FALSE(abc < c_a); 125 EXPECT_TRUE(a < v_abc); 126 EXPECT_FALSE(abc < v_a); 127 128 EXPECT_TRUE(a < def); 129 EXPECT_FALSE(def < a); 130 EXPECT_TRUE(c_a < def); 131 EXPECT_FALSE(c_def < a); 132 EXPECT_TRUE(a < c_def); 133 EXPECT_FALSE(def < c_a); 134 EXPECT_TRUE(a < v_def); 135 EXPECT_FALSE(def < v_a); 136 137 EXPECT_TRUE(abc < def); 138 EXPECT_FALSE(def < abc); 139 EXPECT_TRUE(c_abc < def); 140 EXPECT_FALSE(c_def < abc); 141 EXPECT_TRUE(abc < c_def); 142 EXPECT_FALSE(def < c_abc); 143 EXPECT_TRUE(abc < v_def); 144 EXPECT_FALSE(def < v_abc); 145 } 146 147 TEST(WideString, OperatorEQ) { 148 WideString null_string; 149 EXPECT_TRUE(null_string == null_string); 150 151 WideString empty_string(L""); 152 EXPECT_TRUE(empty_string == empty_string); 153 EXPECT_TRUE(empty_string == null_string); 154 EXPECT_TRUE(null_string == empty_string); 155 156 WideString deleted_string(L"hello"); 157 deleted_string.Delete(0, 5); 158 EXPECT_TRUE(deleted_string == deleted_string); 159 EXPECT_TRUE(deleted_string == null_string); 160 EXPECT_TRUE(deleted_string == empty_string); 161 EXPECT_TRUE(null_string == deleted_string); 162 EXPECT_TRUE(null_string == empty_string); 163 164 WideString wide_string(L"hello"); 165 EXPECT_TRUE(wide_string == wide_string); 166 EXPECT_FALSE(wide_string == null_string); 167 EXPECT_FALSE(wide_string == empty_string); 168 EXPECT_FALSE(wide_string == deleted_string); 169 EXPECT_FALSE(null_string == wide_string); 170 EXPECT_FALSE(empty_string == wide_string); 171 EXPECT_FALSE(deleted_string == wide_string); 172 173 WideString wide_string_same1(L"hello"); 174 EXPECT_TRUE(wide_string == wide_string_same1); 175 EXPECT_TRUE(wide_string_same1 == wide_string); 176 177 WideString wide_string_same2(wide_string); 178 EXPECT_TRUE(wide_string == wide_string_same2); 179 EXPECT_TRUE(wide_string_same2 == wide_string); 180 181 WideString wide_string1(L"he"); 182 WideString wide_string2(L"hellp"); 183 WideString wide_string3(L"hellod"); 184 EXPECT_FALSE(wide_string == wide_string1); 185 EXPECT_FALSE(wide_string == wide_string2); 186 EXPECT_FALSE(wide_string == wide_string3); 187 EXPECT_FALSE(wide_string1 == wide_string); 188 EXPECT_FALSE(wide_string2 == wide_string); 189 EXPECT_FALSE(wide_string3 == wide_string); 190 191 WideStringView null_string_c; 192 WideStringView empty_string_c(L""); 193 EXPECT_TRUE(null_string == null_string_c); 194 EXPECT_TRUE(null_string == empty_string_c); 195 EXPECT_TRUE(empty_string == null_string_c); 196 EXPECT_TRUE(empty_string == empty_string_c); 197 EXPECT_TRUE(deleted_string == null_string_c); 198 EXPECT_TRUE(deleted_string == empty_string_c); 199 EXPECT_TRUE(null_string_c == null_string); 200 EXPECT_TRUE(empty_string_c == null_string); 201 EXPECT_TRUE(null_string_c == empty_string); 202 EXPECT_TRUE(empty_string_c == empty_string); 203 EXPECT_TRUE(null_string_c == deleted_string); 204 EXPECT_TRUE(empty_string_c == deleted_string); 205 206 WideStringView wide_string_c_same1(L"hello"); 207 EXPECT_TRUE(wide_string == wide_string_c_same1); 208 EXPECT_TRUE(wide_string_c_same1 == wide_string); 209 210 WideStringView wide_string_c1(L"he"); 211 WideStringView wide_string_c2(L"hellp"); 212 WideStringView wide_string_c3(L"hellod"); 213 EXPECT_FALSE(wide_string == wide_string_c1); 214 EXPECT_FALSE(wide_string == wide_string_c2); 215 EXPECT_FALSE(wide_string == wide_string_c3); 216 EXPECT_FALSE(wide_string_c1 == wide_string); 217 EXPECT_FALSE(wide_string_c2 == wide_string); 218 EXPECT_FALSE(wide_string_c3 == wide_string); 219 220 const wchar_t* const c_null_string = nullptr; 221 const wchar_t* const c_empty_string = L""; 222 EXPECT_TRUE(null_string == c_null_string); 223 EXPECT_TRUE(null_string == c_empty_string); 224 EXPECT_TRUE(empty_string == c_null_string); 225 EXPECT_TRUE(empty_string == c_empty_string); 226 EXPECT_TRUE(deleted_string == c_null_string); 227 EXPECT_TRUE(deleted_string == c_empty_string); 228 EXPECT_TRUE(c_null_string == null_string); 229 EXPECT_TRUE(c_empty_string == null_string); 230 EXPECT_TRUE(c_null_string == empty_string); 231 EXPECT_TRUE(c_empty_string == empty_string); 232 EXPECT_TRUE(c_null_string == deleted_string); 233 EXPECT_TRUE(c_empty_string == deleted_string); 234 235 const wchar_t* const c_string_same1 = L"hello"; 236 EXPECT_TRUE(wide_string == c_string_same1); 237 EXPECT_TRUE(c_string_same1 == wide_string); 238 239 const wchar_t* const c_string1 = L"he"; 240 const wchar_t* const c_string2 = L"hellp"; 241 const wchar_t* const c_string3 = L"hellod"; 242 EXPECT_FALSE(wide_string == c_string1); 243 EXPECT_FALSE(wide_string == c_string2); 244 EXPECT_FALSE(wide_string == c_string3); 245 EXPECT_FALSE(c_string1 == wide_string); 246 EXPECT_FALSE(c_string2 == wide_string); 247 EXPECT_FALSE(c_string3 == wide_string); 248 } 249 250 TEST(WideString, OperatorNE) { 251 WideString null_string; 252 EXPECT_FALSE(null_string != null_string); 253 254 WideString empty_string(L""); 255 EXPECT_FALSE(empty_string != empty_string); 256 EXPECT_FALSE(empty_string != null_string); 257 EXPECT_FALSE(null_string != empty_string); 258 259 WideString deleted_string(L"hello"); 260 deleted_string.Delete(0, 5); 261 EXPECT_FALSE(deleted_string != deleted_string); 262 EXPECT_FALSE(deleted_string != null_string); 263 EXPECT_FALSE(deleted_string != empty_string); 264 EXPECT_FALSE(null_string != deleted_string); 265 EXPECT_FALSE(null_string != empty_string); 266 267 WideString wide_string(L"hello"); 268 EXPECT_FALSE(wide_string != wide_string); 269 EXPECT_TRUE(wide_string != null_string); 270 EXPECT_TRUE(wide_string != empty_string); 271 EXPECT_TRUE(wide_string != deleted_string); 272 EXPECT_TRUE(null_string != wide_string); 273 EXPECT_TRUE(empty_string != wide_string); 274 EXPECT_TRUE(deleted_string != wide_string); 275 276 WideString wide_string_same1(L"hello"); 277 EXPECT_FALSE(wide_string != wide_string_same1); 278 EXPECT_FALSE(wide_string_same1 != wide_string); 279 280 WideString wide_string_same2(wide_string); 281 EXPECT_FALSE(wide_string != wide_string_same2); 282 EXPECT_FALSE(wide_string_same2 != wide_string); 283 284 WideString wide_string1(L"he"); 285 WideString wide_string2(L"hellp"); 286 WideString wide_string3(L"hellod"); 287 EXPECT_TRUE(wide_string != wide_string1); 288 EXPECT_TRUE(wide_string != wide_string2); 289 EXPECT_TRUE(wide_string != wide_string3); 290 EXPECT_TRUE(wide_string1 != wide_string); 291 EXPECT_TRUE(wide_string2 != wide_string); 292 EXPECT_TRUE(wide_string3 != wide_string); 293 294 WideStringView null_string_c; 295 WideStringView empty_string_c(L""); 296 EXPECT_FALSE(null_string != null_string_c); 297 EXPECT_FALSE(null_string != empty_string_c); 298 EXPECT_FALSE(empty_string != null_string_c); 299 EXPECT_FALSE(empty_string != empty_string_c); 300 EXPECT_FALSE(deleted_string != null_string_c); 301 EXPECT_FALSE(deleted_string != empty_string_c); 302 EXPECT_FALSE(null_string_c != null_string); 303 EXPECT_FALSE(empty_string_c != null_string); 304 EXPECT_FALSE(null_string_c != empty_string); 305 EXPECT_FALSE(empty_string_c != empty_string); 306 307 WideStringView wide_string_c_same1(L"hello"); 308 EXPECT_FALSE(wide_string != wide_string_c_same1); 309 EXPECT_FALSE(wide_string_c_same1 != wide_string); 310 311 WideStringView wide_string_c1(L"he"); 312 WideStringView wide_string_c2(L"hellp"); 313 WideStringView wide_string_c3(L"hellod"); 314 EXPECT_TRUE(wide_string != wide_string_c1); 315 EXPECT_TRUE(wide_string != wide_string_c2); 316 EXPECT_TRUE(wide_string != wide_string_c3); 317 EXPECT_TRUE(wide_string_c1 != wide_string); 318 EXPECT_TRUE(wide_string_c2 != wide_string); 319 EXPECT_TRUE(wide_string_c3 != wide_string); 320 321 const wchar_t* const c_null_string = nullptr; 322 const wchar_t* const c_empty_string = L""; 323 EXPECT_FALSE(null_string != c_null_string); 324 EXPECT_FALSE(null_string != c_empty_string); 325 EXPECT_FALSE(empty_string != c_null_string); 326 EXPECT_FALSE(empty_string != c_empty_string); 327 EXPECT_FALSE(deleted_string != c_null_string); 328 EXPECT_FALSE(deleted_string != c_empty_string); 329 EXPECT_FALSE(c_null_string != null_string); 330 EXPECT_FALSE(c_empty_string != null_string); 331 EXPECT_FALSE(c_null_string != empty_string); 332 EXPECT_FALSE(c_empty_string != empty_string); 333 EXPECT_FALSE(c_null_string != deleted_string); 334 EXPECT_FALSE(c_empty_string != deleted_string); 335 336 const wchar_t* const c_string_same1 = L"hello"; 337 EXPECT_FALSE(wide_string != c_string_same1); 338 EXPECT_FALSE(c_string_same1 != wide_string); 339 340 const wchar_t* const c_string1 = L"he"; 341 const wchar_t* const c_string2 = L"hellp"; 342 const wchar_t* const c_string3 = L"hellod"; 343 EXPECT_TRUE(wide_string != c_string1); 344 EXPECT_TRUE(wide_string != c_string2); 345 EXPECT_TRUE(wide_string != c_string3); 346 EXPECT_TRUE(c_string1 != wide_string); 347 EXPECT_TRUE(c_string2 != wide_string); 348 EXPECT_TRUE(c_string3 != wide_string); 349 } 350 351 TEST(WideString, ConcatInPlace) { 352 WideString fred; 353 fred.Concat(L"FRED", 4); 354 EXPECT_EQ(L"FRED", fred); 355 356 fred.Concat(L"DY", 2); 357 EXPECT_EQ(L"FREDDY", fred); 358 359 fred.Delete(3, 3); 360 EXPECT_EQ(L"FRE", fred); 361 362 fred.Concat(L"D", 1); 363 EXPECT_EQ(L"FRED", fred); 364 365 WideString copy = fred; 366 fred.Concat(L"DY", 2); 367 EXPECT_EQ(L"FREDDY", fred); 368 EXPECT_EQ(L"FRED", copy); 369 } 370 371 TEST(WideString, Remove) { 372 WideString freed(L"FREED"); 373 freed.Remove(L'E'); 374 EXPECT_EQ(L"FRD", freed); 375 freed.Remove(L'F'); 376 EXPECT_EQ(L"RD", freed); 377 freed.Remove(L'D'); 378 EXPECT_EQ(L"R", freed); 379 freed.Remove(L'X'); 380 EXPECT_EQ(L"R", freed); 381 freed.Remove(L'R'); 382 EXPECT_EQ(L"", freed); 383 384 WideString empty; 385 empty.Remove(L'X'); 386 EXPECT_EQ(L"", empty); 387 } 388 389 TEST(WideString, RemoveCopies) { 390 WideString freed(L"FREED"); 391 const wchar_t* old_buffer = freed.c_str(); 392 393 // No change with single reference - no copy. 394 freed.Remove(L'Q'); 395 EXPECT_EQ(L"FREED", freed); 396 EXPECT_EQ(old_buffer, freed.c_str()); 397 398 // Change with single reference - no copy. 399 freed.Remove(L'E'); 400 EXPECT_EQ(L"FRD", freed); 401 EXPECT_EQ(old_buffer, freed.c_str()); 402 403 // No change with multiple references - no copy. 404 WideString shared(freed); 405 freed.Remove(L'Q'); 406 EXPECT_EQ(L"FRD", freed); 407 EXPECT_EQ(old_buffer, freed.c_str()); 408 EXPECT_EQ(old_buffer, shared.c_str()); 409 410 // Change with multiple references -- must copy. 411 freed.Remove(L'D'); 412 EXPECT_EQ(L"FR", freed); 413 EXPECT_NE(old_buffer, freed.c_str()); 414 EXPECT_EQ(L"FRD", shared); 415 EXPECT_EQ(old_buffer, shared.c_str()); 416 } 417 418 TEST(WideString, Replace) { 419 WideString fred(L"FRED"); 420 fred.Replace(L"FR", L"BL"); 421 EXPECT_EQ(L"BLED", fred); 422 fred.Replace(L"D", L"DDY"); 423 EXPECT_EQ(L"BLEDDY", fred); 424 fred.Replace(L"LEDD", L""); 425 EXPECT_EQ(L"BY", fred); 426 fred.Replace(L"X", L"CLAMS"); 427 EXPECT_EQ(L"BY", fred); 428 fred.Replace(L"BY", L"HI"); 429 EXPECT_EQ(L"HI", fred); 430 fred.Replace(L"", L"CLAMS"); 431 EXPECT_EQ(L"HI", fred); 432 fred.Replace(L"HI", L""); 433 EXPECT_EQ(L"", fred); 434 } 435 436 TEST(WideString, Insert) { 437 WideString fred(L"FRED"); 438 EXPECT_EQ(5u, fred.Insert(0, 'S')); 439 EXPECT_EQ(L"SFRED", fred); 440 EXPECT_EQ(6u, fred.Insert(1, 'T')); 441 EXPECT_EQ(L"STFRED", fred); 442 EXPECT_EQ(7u, fred.Insert(4, 'U')); 443 EXPECT_EQ(L"STFRUED", fred); 444 EXPECT_EQ(8u, fred.Insert(7, 'V')); 445 EXPECT_EQ(L"STFRUEDV", fred); 446 EXPECT_EQ(8u, fred.Insert(12, 'P')); 447 EXPECT_EQ(L"STFRUEDV", fred); 448 { 449 WideString empty; 450 EXPECT_EQ(1u, empty.Insert(0, 'X')); 451 EXPECT_EQ(L"X", empty); 452 } 453 { 454 WideString empty; 455 EXPECT_EQ(0u, empty.Insert(5, 'X')); 456 EXPECT_NE(L"X", empty); 457 } 458 } 459 460 TEST(WideString, InsertAtFrontAndInsertAtBack) { 461 { 462 WideString empty; 463 EXPECT_EQ(1u, empty.InsertAtFront('D')); 464 EXPECT_EQ(L"D", empty); 465 EXPECT_EQ(2u, empty.InsertAtFront('E')); 466 EXPECT_EQ(L"ED", empty); 467 EXPECT_EQ(3u, empty.InsertAtFront('R')); 468 EXPECT_EQ(L"RED", empty); 469 EXPECT_EQ(4u, empty.InsertAtFront('F')); 470 EXPECT_EQ(L"FRED", empty); 471 } 472 { 473 WideString empty; 474 EXPECT_EQ(1u, empty.InsertAtBack('F')); 475 EXPECT_EQ(L"F", empty); 476 EXPECT_EQ(2u, empty.InsertAtBack('R')); 477 EXPECT_EQ(L"FR", empty); 478 EXPECT_EQ(3u, empty.InsertAtBack('E')); 479 EXPECT_EQ(L"FRE", empty); 480 EXPECT_EQ(4u, empty.InsertAtBack('D')); 481 EXPECT_EQ(L"FRED", empty); 482 } 483 { 484 WideString empty; 485 EXPECT_EQ(1u, empty.InsertAtBack('E')); 486 EXPECT_EQ(L"E", empty); 487 EXPECT_EQ(2u, empty.InsertAtFront('R')); 488 EXPECT_EQ(L"RE", empty); 489 EXPECT_EQ(3u, empty.InsertAtBack('D')); 490 EXPECT_EQ(L"RED", empty); 491 EXPECT_EQ(4u, empty.InsertAtFront('F')); 492 EXPECT_EQ(L"FRED", empty); 493 } 494 } 495 496 TEST(WideString, Delete) { 497 WideString fred(L"FRED"); 498 EXPECT_EQ(4u, fred.Delete(0, 0)); 499 EXPECT_EQ(L"FRED", fred); 500 EXPECT_EQ(2u, fred.Delete(0, 2)); 501 EXPECT_EQ(L"ED", fred); 502 EXPECT_EQ(1u, fred.Delete(1)); 503 EXPECT_EQ(L"E", fred); 504 EXPECT_EQ(0u, fred.Delete(0)); 505 EXPECT_EQ(L"", fred); 506 EXPECT_EQ(0u, fred.Delete(0)); 507 EXPECT_EQ(L"", fred); 508 509 WideString empty; 510 EXPECT_EQ(0u, empty.Delete(0)); 511 EXPECT_EQ(L"", empty); 512 EXPECT_EQ(0u, empty.Delete(1)); 513 EXPECT_EQ(L"", empty); 514 } 515 516 TEST(WideString, Mid) { 517 WideString fred(L"FRED"); 518 EXPECT_EQ(L"", fred.Mid(0, 0)); 519 EXPECT_EQ(L"", fred.Mid(3, 0)); 520 EXPECT_EQ(L"FRED", fred.Mid(0, 4)); 521 EXPECT_EQ(L"RED", fred.Mid(1, 3)); 522 EXPECT_EQ(L"ED", fred.Mid(2, 2)); 523 EXPECT_EQ(L"D", fred.Mid(3, 1)); 524 EXPECT_EQ(L"F", fred.Mid(0, 1)); 525 EXPECT_EQ(L"R", fred.Mid(1, 1)); 526 EXPECT_EQ(L"E", fred.Mid(2, 1)); 527 EXPECT_EQ(L"D", fred.Mid(3, 1)); 528 EXPECT_EQ(L"FR", fred.Mid(0, 2)); 529 EXPECT_EQ(L"FRED", fred.Mid(0, 4)); 530 EXPECT_EQ(L"", fred.Mid(0, 10)); 531 532 EXPECT_EQ(L"", fred.Mid(1, 4)); 533 EXPECT_EQ(L"", fred.Mid(4, 1)); 534 535 WideString empty; 536 EXPECT_EQ(L"", empty.Mid(0, 0)); 537 } 538 539 TEST(WideString, Left) { 540 WideString fred(L"FRED"); 541 EXPECT_EQ(L"", fred.Left(0)); 542 EXPECT_EQ(L"F", fred.Left(1)); 543 EXPECT_EQ(L"FR", fred.Left(2)); 544 EXPECT_EQ(L"FRE", fred.Left(3)); 545 EXPECT_EQ(L"FRED", fred.Left(4)); 546 547 EXPECT_EQ(L"", fred.Left(5)); 548 549 WideString empty; 550 EXPECT_EQ(L"", empty.Left(0)); 551 EXPECT_EQ(L"", empty.Left(1)); 552 } 553 554 TEST(WideString, Right) { 555 WideString fred(L"FRED"); 556 EXPECT_EQ(L"", fred.Right(0)); 557 EXPECT_EQ(L"D", fred.Right(1)); 558 EXPECT_EQ(L"ED", fred.Right(2)); 559 EXPECT_EQ(L"RED", fred.Right(3)); 560 EXPECT_EQ(L"FRED", fred.Right(4)); 561 562 EXPECT_EQ(L"", fred.Right(5)); 563 564 WideString empty; 565 EXPECT_EQ(L"", empty.Right(0)); 566 EXPECT_EQ(L"", empty.Right(1)); 567 } 568 569 TEST(WideString, Find) { 570 WideString null_string; 571 EXPECT_FALSE(null_string.Find(L'a').has_value()); 572 EXPECT_FALSE(null_string.Find(L'\0').has_value()); 573 574 WideString empty_string(L""); 575 EXPECT_FALSE(empty_string.Find(L'a').has_value()); 576 EXPECT_FALSE(empty_string.Find(L'\0').has_value()); 577 578 Optional<size_t> result; 579 WideString single_string(L"a"); 580 result = single_string.Find(L'a'); 581 ASSERT_TRUE(result.has_value()); 582 EXPECT_EQ(0u, result.value()); 583 EXPECT_FALSE(single_string.Find(L'b').has_value()); 584 EXPECT_FALSE(single_string.Find(L'\0').has_value()); 585 586 WideString longer_string(L"abccc"); 587 result = longer_string.Find(L'a'); 588 ASSERT_TRUE(result.has_value()); 589 EXPECT_EQ(0u, result.value()); 590 result = longer_string.Find(L'c'); 591 ASSERT_TRUE(result.has_value()); 592 EXPECT_EQ(2u, result.value()); 593 result = longer_string.Find(L'c', 3); 594 ASSERT_TRUE(result.has_value()); 595 EXPECT_EQ(3u, result.value()); 596 EXPECT_FALSE(longer_string.Find(L'\0').has_value()); 597 598 result = longer_string.Find(L"ab"); 599 ASSERT_TRUE(result.has_value()); 600 EXPECT_EQ(0u, result.value()); 601 result = longer_string.Find(L"ccc"); 602 ASSERT_TRUE(result.has_value()); 603 EXPECT_EQ(2u, result.value()); 604 result = longer_string.Find(L"cc", 3); 605 ASSERT_TRUE(result.has_value()); 606 EXPECT_EQ(3u, result.value()); 607 EXPECT_FALSE(longer_string.Find(L"d").has_value()); 608 609 WideString hibyte_string( 610 L"ab\xff8c" 611 L"def"); 612 result = hibyte_string.Find(L'\xff8c'); 613 ASSERT_TRUE(result.has_value()); 614 EXPECT_EQ(2u, result.value()); 615 } 616 617 TEST(WideString, UpperLower) { 618 WideString fred(L"F-Re.42D"); 619 fred.MakeLower(); 620 EXPECT_EQ(L"f-re.42d", fred); 621 fred.MakeUpper(); 622 EXPECT_EQ(L"F-RE.42D", fred); 623 624 WideString empty; 625 empty.MakeLower(); 626 EXPECT_EQ(L"", empty); 627 empty.MakeUpper(); 628 EXPECT_EQ(L"", empty); 629 } 630 631 TEST(WideString, Trim) { 632 WideString fred(L" FRED "); 633 fred.Trim(); 634 EXPECT_EQ(L"FRED", fred); 635 fred.Trim(L'E'); 636 EXPECT_EQ(L"FRED", fred); 637 fred.Trim(L'F'); 638 EXPECT_EQ(L"RED", fred); 639 fred.Trim(L"ERP"); 640 EXPECT_EQ(L"D", fred); 641 642 WideString blank(L" "); 643 blank.Trim(L"ERP"); 644 EXPECT_EQ(L" ", blank); 645 blank.Trim(L'E'); 646 EXPECT_EQ(L" ", blank); 647 blank.Trim(); 648 EXPECT_EQ(L"", blank); 649 650 WideString empty; 651 empty.Trim(L"ERP"); 652 EXPECT_EQ(L"", empty); 653 empty.Trim(L'E'); 654 EXPECT_EQ(L"", empty); 655 empty.Trim(); 656 EXPECT_EQ(L"", empty); 657 658 WideString abc(L" ABCCBA "); 659 abc.Trim(L"A"); 660 EXPECT_EQ(L" ABCCBA ", abc); 661 abc.Trim(L" A"); 662 EXPECT_EQ(L"BCCB", abc); 663 } 664 665 TEST(WideString, TrimLeft) { 666 WideString fred(L" FRED "); 667 fred.TrimLeft(); 668 EXPECT_EQ(L"FRED ", fred); 669 fred.TrimLeft(L'E'); 670 EXPECT_EQ(L"FRED ", fred); 671 fred.TrimLeft(L'F'); 672 EXPECT_EQ(L"RED ", fred); 673 fred.TrimLeft(L"ERP"); 674 EXPECT_EQ(L"D ", fred); 675 676 WideString blank(L" "); 677 blank.TrimLeft(L"ERP"); 678 EXPECT_EQ(L" ", blank); 679 blank.TrimLeft(L'E'); 680 EXPECT_EQ(L" ", blank); 681 blank.TrimLeft(); 682 EXPECT_EQ(L"", blank); 683 684 WideString empty; 685 empty.TrimLeft(L"ERP"); 686 EXPECT_EQ(L"", empty); 687 empty.TrimLeft(L'E'); 688 EXPECT_EQ(L"", empty); 689 empty.TrimLeft(); 690 EXPECT_EQ(L"", empty); 691 } 692 693 TEST(WideString, TrimLeftCopies) { 694 { 695 // With a single reference, no copy takes place. 696 WideString fred(L" FRED "); 697 const wchar_t* old_buffer = fred.c_str(); 698 fred.TrimLeft(); 699 EXPECT_EQ(L"FRED ", fred); 700 EXPECT_EQ(old_buffer, fred.c_str()); 701 } 702 { 703 // With multiple references, we must copy. 704 WideString fred(L" FRED "); 705 WideString other_fred = fred; 706 const wchar_t* old_buffer = fred.c_str(); 707 fred.TrimLeft(); 708 EXPECT_EQ(L"FRED ", fred); 709 EXPECT_EQ(L" FRED ", other_fred); 710 EXPECT_NE(old_buffer, fred.c_str()); 711 } 712 { 713 // With multiple references, but no modifications, no copy. 714 WideString fred(L"FRED"); 715 WideString other_fred = fred; 716 const wchar_t* old_buffer = fred.c_str(); 717 fred.TrimLeft(); 718 EXPECT_EQ(L"FRED", fred); 719 EXPECT_EQ(L"FRED", other_fred); 720 EXPECT_EQ(old_buffer, fred.c_str()); 721 } 722 } 723 724 TEST(WideString, TrimRight) { 725 WideString fred(L" FRED "); 726 fred.TrimRight(); 727 EXPECT_EQ(L" FRED", fred); 728 fred.TrimRight(L'E'); 729 EXPECT_EQ(L" FRED", fred); 730 fred.TrimRight(L'D'); 731 EXPECT_EQ(L" FRE", fred); 732 fred.TrimRight(L"ERP"); 733 EXPECT_EQ(L" F", fred); 734 735 WideString blank(L" "); 736 blank.TrimRight(L"ERP"); 737 EXPECT_EQ(L" ", blank); 738 blank.TrimRight(L'E'); 739 EXPECT_EQ(L" ", blank); 740 blank.TrimRight(); 741 EXPECT_EQ(L"", blank); 742 743 WideString empty; 744 empty.TrimRight(L"ERP"); 745 EXPECT_EQ(L"", empty); 746 empty.TrimRight(L'E'); 747 EXPECT_EQ(L"", empty); 748 empty.TrimRight(); 749 EXPECT_EQ(L"", empty); 750 } 751 752 TEST(WideString, TrimRightCopies) { 753 { 754 // With a single reference, no copy takes place. 755 WideString fred(L" FRED "); 756 const wchar_t* old_buffer = fred.c_str(); 757 fred.TrimRight(); 758 EXPECT_EQ(L" FRED", fred); 759 EXPECT_EQ(old_buffer, fred.c_str()); 760 } 761 { 762 // With multiple references, we must copy. 763 WideString fred(L" FRED "); 764 WideString other_fred = fred; 765 const wchar_t* old_buffer = fred.c_str(); 766 fred.TrimRight(); 767 EXPECT_EQ(L" FRED", fred); 768 EXPECT_EQ(L" FRED ", other_fred); 769 EXPECT_NE(old_buffer, fred.c_str()); 770 } 771 { 772 // With multiple references, but no modifications, no copy. 773 WideString fred(L"FRED"); 774 WideString other_fred = fred; 775 const wchar_t* old_buffer = fred.c_str(); 776 fred.TrimRight(); 777 EXPECT_EQ(L"FRED", fred); 778 EXPECT_EQ(L"FRED", other_fred); 779 EXPECT_EQ(old_buffer, fred.c_str()); 780 } 781 } 782 783 TEST(WideString, Reserve) { 784 { 785 WideString str; 786 str.Reserve(6); 787 const wchar_t* old_buffer = str.c_str(); 788 str += L"ABCDEF"; 789 EXPECT_EQ(old_buffer, str.c_str()); 790 str += L"Blah Blah Blah Blah Blah Blah"; 791 EXPECT_NE(old_buffer, str.c_str()); 792 } 793 { 794 WideString str(L"A"); 795 str.Reserve(6); 796 const wchar_t* old_buffer = str.c_str(); 797 str += L"BCDEF"; 798 EXPECT_EQ(old_buffer, str.c_str()); 799 str += L"Blah Blah Blah Blah Blah Blah"; 800 EXPECT_NE(old_buffer, str.c_str()); 801 } 802 } 803 804 TEST(WideString, GetBuffer) { 805 { 806 WideString str; 807 wchar_t* buffer = str.GetBuffer(12); 808 wcscpy(buffer, L"clams"); 809 str.ReleaseBuffer(str.GetStringLength()); 810 EXPECT_EQ(L"clams", str); 811 } 812 { 813 WideString str(L"cl"); 814 wchar_t* buffer = str.GetBuffer(12); 815 wcscpy(buffer + 2, L"ams"); 816 str.ReleaseBuffer(str.GetStringLength()); 817 EXPECT_EQ(L"clams", str); 818 } 819 } 820 821 TEST(WideString, ReleaseBuffer) { 822 { 823 WideString str; 824 str.Reserve(12); 825 str += L"clams"; 826 const wchar_t* old_buffer = str.c_str(); 827 str.ReleaseBuffer(4); 828 EXPECT_EQ(old_buffer, str.c_str()); 829 EXPECT_EQ(L"clam", str); 830 } 831 { 832 WideString str(L"c"); 833 str.Reserve(12); 834 str += L"lams"; 835 const wchar_t* old_buffer = str.c_str(); 836 str.ReleaseBuffer(4); 837 EXPECT_EQ(old_buffer, str.c_str()); 838 EXPECT_EQ(L"clam", str); 839 } 840 { 841 WideString str; 842 str.Reserve(200); 843 str += L"clams"; 844 const wchar_t* old_buffer = str.c_str(); 845 str.ReleaseBuffer(4); 846 EXPECT_NE(old_buffer, str.c_str()); 847 EXPECT_EQ(L"clam", str); 848 } 849 { 850 WideString str(L"c"); 851 str.Reserve(200); 852 str += L"lams"; 853 const wchar_t* old_buffer = str.c_str(); 854 str.ReleaseBuffer(4); 855 EXPECT_NE(old_buffer, str.c_str()); 856 EXPECT_EQ(L"clam", str); 857 } 858 } 859 860 TEST(WideString, EmptyReverseIterator) { 861 WideString empty; 862 auto iter = empty.rbegin(); 863 EXPECT_TRUE(iter == empty.rend()); 864 EXPECT_FALSE(iter != empty.rend()); 865 EXPECT_FALSE(iter < empty.rend()); 866 } 867 868 TEST(WideString, OneCharReverseIterator) { 869 WideString one_str(L"a"); 870 auto iter = one_str.rbegin(); 871 EXPECT_FALSE(iter == one_str.rend()); 872 EXPECT_TRUE(iter != one_str.rend()); 873 EXPECT_TRUE(iter < one_str.rend()); 874 875 char ch = *iter++; 876 EXPECT_EQ('a', ch); 877 EXPECT_TRUE(iter == one_str.rend()); 878 EXPECT_FALSE(iter != one_str.rend()); 879 EXPECT_FALSE(iter < one_str.rend()); 880 } 881 882 TEST(WideString, MultiCharReverseIterator) { 883 WideString multi_str(L"abcd"); 884 auto iter = multi_str.rbegin(); 885 EXPECT_FALSE(iter == multi_str.rend()); 886 887 char ch = *iter++; 888 EXPECT_EQ('d', ch); 889 EXPECT_EQ('c', *iter); 890 EXPECT_FALSE(iter == multi_str.rend()); 891 892 ch = *(++iter); 893 EXPECT_EQ('b', ch); 894 EXPECT_EQ('b', *iter); 895 EXPECT_FALSE(iter == multi_str.rend()); 896 897 ch = *iter++; 898 EXPECT_EQ('b', ch); 899 EXPECT_EQ('a', *iter); 900 EXPECT_FALSE(iter == multi_str.rend()); 901 902 ch = *iter++; 903 EXPECT_EQ('a', ch); 904 EXPECT_TRUE(iter == multi_str.rend()); 905 906 ch = *(--iter); 907 EXPECT_EQ('a', ch); 908 EXPECT_EQ('a', *iter); 909 EXPECT_FALSE(iter == multi_str.rend()); 910 911 ch = *iter--; 912 EXPECT_EQ('a', ch); 913 EXPECT_EQ('b', *iter); 914 EXPECT_FALSE(iter == multi_str.rend()); 915 916 ch = *iter--; 917 EXPECT_EQ('b', ch); 918 EXPECT_EQ('c', *iter); 919 EXPECT_FALSE(iter == multi_str.rend()); 920 921 ch = *(--iter); 922 EXPECT_EQ('d', ch); 923 EXPECT_EQ('d', *iter); 924 EXPECT_TRUE(iter == multi_str.rbegin()); 925 } 926 927 TEST(WideString, UTF16LE_Encode) { 928 struct UTF16LEEncodeCase { 929 WideString ws; 930 ByteString bs; 931 } const utf16le_encode_cases[] = { 932 {L"", ByteString("\0\0", 2)}, 933 {L"abc", ByteString("a\0b\0c\0\0\0", 8)}, 934 {L"abcdef", ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)}, 935 {L"abc\0def", ByteString("a\0b\0c\0\0\0", 8)}, 936 {L"\xaabb\xccdd", ByteString("\xbb\xaa\xdd\xcc\0\0", 6)}, 937 {L"\x3132\x6162", ByteString("\x32\x31\x62\x61\0\0", 6)}, 938 }; 939 940 for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) { 941 EXPECT_EQ(utf16le_encode_cases[i].bs, 942 utf16le_encode_cases[i].ws.UTF16LE_Encode()) 943 << " for case number " << i; 944 } 945 } 946 947 TEST(WideStringView, FromVector) { 948 std::vector<WideStringView::UnsignedType> null_vec; 949 WideStringView null_string(null_vec); 950 EXPECT_EQ(0u, null_string.GetLength()); 951 952 std::vector<WideStringView::UnsignedType> lower_a_vec( 953 10, static_cast<WideStringView::UnsignedType>(L'a')); 954 WideStringView lower_a_string(lower_a_vec); 955 EXPECT_EQ(10u, lower_a_string.GetLength()); 956 EXPECT_EQ(L"aaaaaaaaaa", lower_a_string); 957 958 std::vector<WideStringView::UnsignedType> cleared_vec; 959 cleared_vec.push_back(42); 960 cleared_vec.pop_back(); 961 WideStringView cleared_string(cleared_vec); 962 EXPECT_EQ(0u, cleared_string.GetLength()); 963 EXPECT_EQ(nullptr, cleared_string.raw_str()); 964 } 965 966 TEST(WideStringView, ElementAccess) { 967 WideStringView abc(L"abc"); 968 EXPECT_EQ(L'a', static_cast<wchar_t>(abc[0])); 969 EXPECT_EQ(L'b', static_cast<wchar_t>(abc[1])); 970 EXPECT_EQ(L'c', static_cast<wchar_t>(abc[2])); 971 #ifndef NDEBUG 972 EXPECT_DEATH({ abc[4]; }, ".*"); 973 #endif 974 } 975 976 TEST(WideStringView, OperatorLT) { 977 WideStringView empty; 978 WideStringView a(L"a"); 979 WideStringView abc(L"\x0110qq"); // Comes InsertAtFront despite endianness. 980 WideStringView def(L"\x1001qq"); // Comes InsertAtBack despite endianness. 981 const wchar_t* const c_null = nullptr; 982 const wchar_t* const c_empty = L""; 983 const wchar_t* const c_a = L"a"; 984 const wchar_t* const c_abc = L"\x0110qq"; 985 const wchar_t* const c_def = L"\x1001qq"; 986 987 EXPECT_FALSE(empty < empty); 988 EXPECT_FALSE(a < a); 989 EXPECT_FALSE(abc < abc); 990 EXPECT_FALSE(def < def); 991 EXPECT_FALSE(c_null < empty); 992 EXPECT_FALSE(c_empty < empty); 993 EXPECT_FALSE(c_a < a); 994 EXPECT_FALSE(c_abc < abc); 995 EXPECT_FALSE(c_def < def); 996 EXPECT_FALSE(empty < c_null); 997 EXPECT_FALSE(empty < c_empty); 998 EXPECT_FALSE(a < c_a); 999 EXPECT_FALSE(abc < c_abc); 1000 EXPECT_FALSE(def < c_def); 1001 1002 EXPECT_TRUE(empty < a); 1003 EXPECT_FALSE(a < empty); 1004 EXPECT_TRUE(empty < c_a); 1005 EXPECT_FALSE(a < c_null); 1006 EXPECT_FALSE(a < c_empty); 1007 1008 EXPECT_TRUE(empty < abc); 1009 EXPECT_FALSE(abc < empty); 1010 EXPECT_TRUE(empty < c_abc); 1011 EXPECT_FALSE(abc < c_null); 1012 EXPECT_FALSE(abc < c_empty); 1013 1014 EXPECT_TRUE(empty < def); 1015 EXPECT_FALSE(def < empty); 1016 EXPECT_TRUE(empty < c_def); 1017 EXPECT_FALSE(def < c_null); 1018 EXPECT_FALSE(def < c_empty); 1019 1020 EXPECT_TRUE(a < abc); 1021 EXPECT_FALSE(abc < a); 1022 EXPECT_TRUE(a < c_abc); 1023 EXPECT_FALSE(abc < c_a); 1024 1025 EXPECT_TRUE(a < def); 1026 EXPECT_FALSE(def < a); 1027 EXPECT_TRUE(a < c_def); 1028 EXPECT_FALSE(def < c_a); 1029 1030 EXPECT_TRUE(abc < def); 1031 EXPECT_FALSE(def < abc); 1032 EXPECT_TRUE(abc < c_def); 1033 EXPECT_FALSE(def < c_abc); 1034 } 1035 1036 TEST(WideStringView, OperatorEQ) { 1037 WideStringView wide_string_c(L"hello"); 1038 EXPECT_TRUE(wide_string_c == wide_string_c); 1039 1040 WideStringView wide_string_c_same1(L"hello"); 1041 EXPECT_TRUE(wide_string_c == wide_string_c_same1); 1042 EXPECT_TRUE(wide_string_c_same1 == wide_string_c); 1043 1044 WideStringView wide_string_c_same2(wide_string_c); 1045 EXPECT_TRUE(wide_string_c == wide_string_c_same2); 1046 EXPECT_TRUE(wide_string_c_same2 == wide_string_c); 1047 1048 WideStringView wide_string_c1(L"he"); 1049 WideStringView wide_string_c2(L"hellp"); 1050 WideStringView wide_string_c3(L"hellod"); 1051 EXPECT_FALSE(wide_string_c == wide_string_c1); 1052 EXPECT_FALSE(wide_string_c == wide_string_c2); 1053 EXPECT_FALSE(wide_string_c == wide_string_c3); 1054 EXPECT_FALSE(wide_string_c1 == wide_string_c); 1055 EXPECT_FALSE(wide_string_c2 == wide_string_c); 1056 EXPECT_FALSE(wide_string_c3 == wide_string_c); 1057 1058 WideString wide_string_same1(L"hello"); 1059 EXPECT_TRUE(wide_string_c == wide_string_same1); 1060 EXPECT_TRUE(wide_string_same1 == wide_string_c); 1061 1062 WideString wide_string1(L"he"); 1063 WideString wide_string2(L"hellp"); 1064 WideString wide_string3(L"hellod"); 1065 EXPECT_FALSE(wide_string_c == wide_string1); 1066 EXPECT_FALSE(wide_string_c == wide_string2); 1067 EXPECT_FALSE(wide_string_c == wide_string3); 1068 EXPECT_FALSE(wide_string1 == wide_string_c); 1069 EXPECT_FALSE(wide_string2 == wide_string_c); 1070 EXPECT_FALSE(wide_string3 == wide_string_c); 1071 1072 const wchar_t* const c_string_same1 = L"hello"; 1073 EXPECT_TRUE(wide_string_c == c_string_same1); 1074 EXPECT_TRUE(c_string_same1 == wide_string_c); 1075 1076 const wchar_t* const c_string1 = L"he"; 1077 const wchar_t* const c_string2 = L"hellp"; 1078 const wchar_t* const c_string3 = L"hellod"; 1079 EXPECT_FALSE(wide_string_c == c_string1); 1080 EXPECT_FALSE(wide_string_c == c_string2); 1081 EXPECT_FALSE(wide_string_c == c_string3); 1082 1083 EXPECT_FALSE(c_string1 == wide_string_c); 1084 EXPECT_FALSE(c_string2 == wide_string_c); 1085 EXPECT_FALSE(c_string3 == wide_string_c); 1086 } 1087 1088 TEST(WideStringView, OperatorNE) { 1089 WideStringView wide_string_c(L"hello"); 1090 EXPECT_FALSE(wide_string_c != wide_string_c); 1091 1092 WideStringView wide_string_c_same1(L"hello"); 1093 EXPECT_FALSE(wide_string_c != wide_string_c_same1); 1094 EXPECT_FALSE(wide_string_c_same1 != wide_string_c); 1095 1096 WideStringView wide_string_c_same2(wide_string_c); 1097 EXPECT_FALSE(wide_string_c != wide_string_c_same2); 1098 EXPECT_FALSE(wide_string_c_same2 != wide_string_c); 1099 1100 WideStringView wide_string_c1(L"he"); 1101 WideStringView wide_string_c2(L"hellp"); 1102 WideStringView wide_string_c3(L"hellod"); 1103 EXPECT_TRUE(wide_string_c != wide_string_c1); 1104 EXPECT_TRUE(wide_string_c != wide_string_c2); 1105 EXPECT_TRUE(wide_string_c != wide_string_c3); 1106 EXPECT_TRUE(wide_string_c1 != wide_string_c); 1107 EXPECT_TRUE(wide_string_c2 != wide_string_c); 1108 EXPECT_TRUE(wide_string_c3 != wide_string_c); 1109 1110 WideString wide_string_same1(L"hello"); 1111 EXPECT_FALSE(wide_string_c != wide_string_same1); 1112 EXPECT_FALSE(wide_string_same1 != wide_string_c); 1113 1114 WideString wide_string1(L"he"); 1115 WideString wide_string2(L"hellp"); 1116 WideString wide_string3(L"hellod"); 1117 EXPECT_TRUE(wide_string_c != wide_string1); 1118 EXPECT_TRUE(wide_string_c != wide_string2); 1119 EXPECT_TRUE(wide_string_c != wide_string3); 1120 EXPECT_TRUE(wide_string1 != wide_string_c); 1121 EXPECT_TRUE(wide_string2 != wide_string_c); 1122 EXPECT_TRUE(wide_string3 != wide_string_c); 1123 1124 const wchar_t* const c_string_same1 = L"hello"; 1125 EXPECT_FALSE(wide_string_c != c_string_same1); 1126 EXPECT_FALSE(c_string_same1 != wide_string_c); 1127 1128 const wchar_t* const c_string1 = L"he"; 1129 const wchar_t* const c_string2 = L"hellp"; 1130 const wchar_t* const c_string3 = L"hellod"; 1131 EXPECT_TRUE(wide_string_c != c_string1); 1132 EXPECT_TRUE(wide_string_c != c_string2); 1133 EXPECT_TRUE(wide_string_c != c_string3); 1134 1135 EXPECT_TRUE(c_string1 != wide_string_c); 1136 EXPECT_TRUE(c_string2 != wide_string_c); 1137 EXPECT_TRUE(c_string3 != wide_string_c); 1138 } 1139 1140 TEST(WideStringView, Find) { 1141 WideStringView null_string; 1142 EXPECT_FALSE(null_string.Find(L'a').has_value()); 1143 EXPECT_FALSE(null_string.Find(L'\0').has_value()); 1144 1145 WideStringView empty_string(L""); 1146 EXPECT_FALSE(empty_string.Find(L'a').has_value()); 1147 EXPECT_FALSE(empty_string.Find(L'\0').has_value()); 1148 1149 Optional<size_t> result; 1150 WideStringView single_string(L"a"); 1151 result = single_string.Find(L'a'); 1152 ASSERT_TRUE(result.has_value()); 1153 EXPECT_EQ(0u, result.value()); 1154 EXPECT_FALSE(single_string.Find(L'b').has_value()); 1155 EXPECT_FALSE(single_string.Find(L'\0').has_value()); 1156 1157 WideStringView longer_string(L"abccc"); 1158 result = longer_string.Find(L'a'); 1159 ASSERT_TRUE(result.has_value()); 1160 EXPECT_EQ(0u, result.value()); 1161 result = longer_string.Find(L'c'); 1162 ASSERT_TRUE(result.has_value()); 1163 EXPECT_EQ(2u, result.value()); 1164 EXPECT_FALSE(longer_string.Find(L'd').has_value()); 1165 EXPECT_FALSE(longer_string.Find(L'\0').has_value()); 1166 1167 WideStringView hibyte_string( 1168 L"ab\xFF8c" 1169 L"def"); 1170 result = hibyte_string.Find(L'\xFF8c'); 1171 ASSERT_TRUE(result.has_value()); 1172 EXPECT_EQ(2u, result.value()); 1173 } 1174 1175 TEST(WideStringView, NullIterator) { 1176 WideStringView null_str; 1177 int32_t sum = 0; 1178 bool any_present = false; 1179 for (const auto& c : null_str) { 1180 sum += c; // Avoid unused arg warnings. 1181 any_present = true; 1182 } 1183 EXPECT_FALSE(any_present); 1184 EXPECT_EQ(0, sum); 1185 } 1186 1187 TEST(WideStringView, EmptyIterator) { 1188 WideStringView empty_str(L""); 1189 int32_t sum = 0; 1190 bool any_present = false; 1191 for (const auto& c : empty_str) { 1192 any_present = true; 1193 sum += c; // Avoid unused arg warnings. 1194 } 1195 EXPECT_FALSE(any_present); 1196 EXPECT_EQ(0, sum); 1197 } 1198 1199 TEST(WideStringView, OneCharIterator) { 1200 WideStringView one_str(L"a"); 1201 int32_t sum = 0; 1202 bool any_present = false; 1203 for (const auto& c : one_str) { 1204 any_present = true; 1205 sum += c; // Avoid unused arg warnings. 1206 } 1207 EXPECT_TRUE(any_present); 1208 EXPECT_EQ(static_cast<int32_t>(L'a'), sum); 1209 } 1210 1211 TEST(WideStringView, MultiCharIterator) { 1212 WideStringView one_str(L"abc"); 1213 int32_t sum = 0; 1214 bool any_present = false; 1215 for (const auto& c : one_str) { 1216 any_present = true; 1217 sum += c; // Avoid unused arg warnings. 1218 } 1219 EXPECT_TRUE(any_present); 1220 EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum); 1221 } 1222 1223 TEST(WideStringView, EmptyReverseIterator) { 1224 WideStringView empty; 1225 auto iter = empty.rbegin(); 1226 EXPECT_TRUE(iter == empty.rend()); 1227 EXPECT_FALSE(iter != empty.rend()); 1228 EXPECT_FALSE(iter < empty.rend()); 1229 } 1230 1231 TEST(WideStringView, OneCharReverseIterator) { 1232 WideStringView one_str(L"a"); 1233 auto iter = one_str.rbegin(); 1234 EXPECT_FALSE(iter == one_str.rend()); 1235 EXPECT_TRUE(iter != one_str.rend()); 1236 EXPECT_TRUE(iter < one_str.rend()); 1237 1238 char ch = *iter++; 1239 EXPECT_EQ('a', ch); 1240 EXPECT_TRUE(iter == one_str.rend()); 1241 EXPECT_FALSE(iter != one_str.rend()); 1242 EXPECT_FALSE(iter < one_str.rend()); 1243 } 1244 1245 TEST(WideStringView, MultiCharReverseIterator) { 1246 WideStringView multi_str(L"abcd"); 1247 auto iter = multi_str.rbegin(); 1248 EXPECT_FALSE(iter == multi_str.rend()); 1249 1250 char ch = *iter++; 1251 EXPECT_EQ('d', ch); 1252 EXPECT_EQ('c', *iter); 1253 EXPECT_FALSE(iter == multi_str.rend()); 1254 1255 ch = *(++iter); 1256 EXPECT_EQ('b', ch); 1257 EXPECT_EQ('b', *iter); 1258 EXPECT_FALSE(iter == multi_str.rend()); 1259 1260 ch = *iter++; 1261 EXPECT_EQ('b', ch); 1262 EXPECT_EQ('a', *iter); 1263 EXPECT_FALSE(iter == multi_str.rend()); 1264 1265 ch = *iter++; 1266 EXPECT_EQ('a', ch); 1267 EXPECT_TRUE(iter == multi_str.rend()); 1268 1269 ch = *(--iter); 1270 EXPECT_EQ('a', ch); 1271 EXPECT_EQ('a', *iter); 1272 EXPECT_FALSE(iter == multi_str.rend()); 1273 1274 ch = *iter--; 1275 EXPECT_EQ('a', ch); 1276 EXPECT_EQ('b', *iter); 1277 EXPECT_FALSE(iter == multi_str.rend()); 1278 1279 ch = *iter--; 1280 EXPECT_EQ('b', ch); 1281 EXPECT_EQ('c', *iter); 1282 EXPECT_FALSE(iter == multi_str.rend()); 1283 1284 ch = *(--iter); 1285 EXPECT_EQ('d', ch); 1286 EXPECT_EQ('d', *iter); 1287 EXPECT_TRUE(iter == multi_str.rbegin()); 1288 } 1289 1290 TEST(WideStringView, AnyAllNoneOf) { 1291 WideStringView str(L"aaaaaaaaaaaaaaaaab"); 1292 EXPECT_FALSE(std::all_of(str.begin(), str.end(), 1293 [](const wchar_t& c) { return c == L'a'; })); 1294 1295 EXPECT_FALSE(std::none_of(str.begin(), str.end(), 1296 [](const wchar_t& c) { return c == L'a'; })); 1297 1298 EXPECT_TRUE(std::any_of(str.begin(), str.end(), 1299 [](const wchar_t& c) { return c == L'a'; })); 1300 1301 EXPECT_TRUE(pdfium::ContainsValue(str, L'a')); 1302 EXPECT_TRUE(pdfium::ContainsValue(str, L'b')); 1303 EXPECT_FALSE(pdfium::ContainsValue(str, L'z')); 1304 } 1305 1306 TEST(WideStringView, TrimmedRight) { 1307 WideStringView fred(L"FRED"); 1308 EXPECT_EQ(L"FRED", fred.TrimmedRight(L'E')); 1309 EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D')); 1310 WideStringView fredd(L"FREDD"); 1311 EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D')); 1312 } 1313 1314 TEST(WideString, FormatWidth) { 1315 EXPECT_EQ(L" 1", WideString::Format(L"%5d", 1)); 1316 EXPECT_EQ(L"1", WideString::Format(L"%d", 1)); 1317 EXPECT_EQ(L" 1", WideString::Format(L"%*d", 5, 1)); 1318 EXPECT_EQ(L"1", WideString::Format(L"%-1d", 1)); 1319 EXPECT_EQ(L"1", WideString::Format(L"%0d", 1)); 1320 EXPECT_EQ(L"", WideString::Format(L"%1048576d", 1)); 1321 } 1322 1323 TEST(WideString, FormatPrecision) { 1324 EXPECT_EQ(L"1.12", WideString::Format(L"%.2f", 1.12345)); 1325 EXPECT_EQ(L"1.123", WideString::Format(L"%.*f", 3, 1.12345)); 1326 EXPECT_EQ(L"1.123450", WideString::Format(L"%f", 1.12345)); 1327 EXPECT_EQ(L"1.123450", WideString::Format(L"%-1f", 1.12345)); 1328 EXPECT_EQ(L"1.123450", WideString::Format(L"%0f", 1.12345)); 1329 EXPECT_EQ(L"", WideString::Format(L"%.1048576f", 1.2)); 1330 } 1331 1332 TEST(WideString, FormatOutOfRangeChar) { 1333 EXPECT_NE(L"", WideString::Format(L"unsupported char '%c'", 0x00FF00FF)); 1334 } 1335 1336 TEST(WideString, Empty) { 1337 WideString empty_str; 1338 EXPECT_TRUE(empty_str.IsEmpty()); 1339 EXPECT_EQ(0u, empty_str.GetLength()); 1340 const wchar_t* cstr = empty_str.c_str(); 1341 EXPECT_EQ(0u, wcslen(cstr)); 1342 } 1343 1344 TEST(CFX_WidString, InitializerList) { 1345 WideString many_str({L"clams", L" and ", L"oysters"}); 1346 EXPECT_EQ(L"clams and oysters", many_str); 1347 many_str = {L"fish", L" and ", L"chips", L" and ", L"soda"}; 1348 EXPECT_EQ(L"fish and chips and soda", many_str); 1349 } 1350 1351 TEST(WideString, NullIterator) { 1352 WideString null_str; 1353 int32_t sum = 0; 1354 bool any_present = false; 1355 for (const auto& c : null_str) { 1356 sum += c; // Avoid unused arg warnings. 1357 any_present = true; 1358 } 1359 EXPECT_FALSE(any_present); 1360 EXPECT_EQ(0, sum); 1361 } 1362 1363 TEST(WideString, EmptyIterator) { 1364 WideString empty_str(L""); 1365 int32_t sum = 0; 1366 bool any_present = false; 1367 for (const auto& c : empty_str) { 1368 any_present = true; 1369 sum += c; // Avoid unused arg warnings. 1370 } 1371 EXPECT_FALSE(any_present); 1372 EXPECT_EQ(0, sum); 1373 } 1374 1375 TEST(WideString, OneCharIterator) { 1376 WideString one_str(L"a"); 1377 int32_t sum = 0; 1378 bool any_present = false; 1379 for (const auto& c : one_str) { 1380 any_present = true; 1381 sum += c; // Avoid unused arg warnings. 1382 } 1383 EXPECT_TRUE(any_present); 1384 EXPECT_EQ(static_cast<int32_t>(L'a'), sum); 1385 } 1386 1387 TEST(WideString, MultiCharIterator) { 1388 WideString one_str(L"abc"); 1389 int32_t sum = 0; 1390 bool any_present = false; 1391 for (const auto& c : one_str) { 1392 any_present = true; 1393 sum += c; // Avoid unused arg warnings. 1394 } 1395 EXPECT_TRUE(any_present); 1396 EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum); 1397 } 1398 1399 TEST(WideString, AnyAllNoneOf) { 1400 WideString str(L"aaaaaaaaaaaaaaaaab"); 1401 EXPECT_FALSE(std::all_of(str.begin(), str.end(), 1402 [](const wchar_t& c) { return c == L'a'; })); 1403 1404 EXPECT_FALSE(std::none_of(str.begin(), str.end(), 1405 [](const wchar_t& c) { return c == L'a'; })); 1406 1407 EXPECT_TRUE(std::any_of(str.begin(), str.end(), 1408 [](const wchar_t& c) { return c == L'a'; })); 1409 1410 EXPECT_TRUE(pdfium::ContainsValue(str, L'a')); 1411 EXPECT_TRUE(pdfium::ContainsValue(str, L'b')); 1412 EXPECT_FALSE(pdfium::ContainsValue(str, L'z')); 1413 } 1414 1415 TEST(WideString, OStreamOverload) { 1416 std::ostringstream stream; 1417 1418 // Basic case, empty string 1419 WideString str; 1420 stream << str; 1421 EXPECT_EQ("", stream.str()); 1422 1423 // Basic case, wide character 1424 str = L"\u20AC"; 1425 stream << str; 1426 EXPECT_EQ("\u20AC", stream.str()); 1427 1428 // Basic case, non-empty string 1429 str = L"def"; 1430 stream.str(""); 1431 stream << "abc" << str << "ghi"; 1432 EXPECT_EQ("abcdefghi", stream.str()); 1433 1434 // Changing the WideString does not change the stream it was written to. 1435 str = L"123"; 1436 EXPECT_EQ("abcdefghi", stream.str()); 1437 1438 // Writing it again to the stream will use the latest value. 1439 stream.str(""); 1440 stream << "abc" << str << "ghi"; 1441 EXPECT_EQ("abc123ghi", stream.str()); 1442 1443 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1444 1445 // Writing a WideString with nulls and no specified length treats it as 1446 // a C-style null-terminated string. 1447 str = WideString(stringWithNulls); 1448 EXPECT_EQ(2u, str.GetLength()); 1449 stream.str(""); 1450 stream << str; 1451 EXPECT_EQ(2u, stream.tellp()); 1452 1453 // Writing a WideString with nulls but specifying its length treats it as 1454 // a C++-style string. 1455 str = WideString(stringWithNulls, 4); 1456 EXPECT_EQ(4u, str.GetLength()); 1457 stream.str(""); 1458 stream << str; 1459 EXPECT_EQ(4u, stream.tellp()); 1460 1461 // << operators can be chained. 1462 WideString str1(L"abc"); 1463 WideString str2(L"def"); 1464 stream.str(""); 1465 stream << str1 << str2; 1466 EXPECT_EQ("abcdef", stream.str()); 1467 } 1468 1469 TEST(WideString, WideOStreamOverload) { 1470 std::wostringstream stream; 1471 1472 // Basic case, empty string 1473 WideString str; 1474 stream << str; 1475 EXPECT_EQ(L"", stream.str()); 1476 1477 // Basic case, wide character 1478 str = L"\u20AC"; 1479 stream << str; 1480 EXPECT_EQ(L"\u20AC", stream.str()); 1481 1482 // Basic case, non-empty string 1483 str = L"def"; 1484 stream.str(L""); 1485 stream << L"abc" << str << L"ghi"; 1486 EXPECT_EQ(L"abcdefghi", stream.str()); 1487 1488 // Changing the WideString does not change the stream it was written to. 1489 str = L"123"; 1490 EXPECT_EQ(L"abcdefghi", stream.str()); 1491 1492 // Writing it again to the stream will use the latest value. 1493 stream.str(L""); 1494 stream << L"abc" << str << L"ghi"; 1495 EXPECT_EQ(L"abc123ghi", stream.str()); 1496 1497 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1498 1499 // Writing a WideString with nulls and no specified length treats it as 1500 // a C-style null-terminated string. 1501 str = WideString(stringWithNulls); 1502 EXPECT_EQ(2u, str.GetLength()); 1503 stream.str(L""); 1504 stream << str; 1505 EXPECT_EQ(2u, stream.tellp()); 1506 1507 // Writing a WideString with nulls but specifying its length treats it as 1508 // a C++-style string. 1509 str = WideString(stringWithNulls, 4); 1510 EXPECT_EQ(4u, str.GetLength()); 1511 stream.str(L""); 1512 stream << str; 1513 EXPECT_EQ(4u, stream.tellp()); 1514 1515 // << operators can be chained. 1516 WideString str1(L"abc"); 1517 WideString str2(L"def"); 1518 stream.str(L""); 1519 stream << str1 << str2; 1520 EXPECT_EQ(L"abcdef", stream.str()); 1521 } 1522 1523 TEST(WideStringView, OStreamOverload) { 1524 // Basic case, empty string 1525 { 1526 std::ostringstream stream; 1527 WideStringView str; 1528 stream << str; 1529 EXPECT_EQ("", stream.str()); 1530 } 1531 1532 // Basic case, non-empty string 1533 { 1534 std::ostringstream stream; 1535 WideStringView str(L"def"); 1536 stream << "abc" << str << "ghi"; 1537 EXPECT_EQ("abcdefghi", stream.str()); 1538 } 1539 1540 // Basic case, wide character 1541 { 1542 std::ostringstream stream; 1543 WideStringView str(L"\u20AC"); 1544 stream << str; 1545 EXPECT_EQ("\u20AC", stream.str()); 1546 } 1547 1548 // Changing the WideStringView does not change the stream it was written to. 1549 { 1550 std::ostringstream stream; 1551 WideStringView str(L"abc"); 1552 stream << str; 1553 str = L"123"; 1554 EXPECT_EQ("abc", stream.str()); 1555 } 1556 1557 // Writing it again to the stream will use the latest value. 1558 { 1559 std::ostringstream stream; 1560 WideStringView str(L"abc"); 1561 stream << str; 1562 stream.str(""); 1563 str = L"123"; 1564 stream << str; 1565 EXPECT_EQ("123", stream.str()); 1566 } 1567 1568 // Writing a WideStringView with nulls and no specified length treats it as 1569 // a C-style null-terminated string. 1570 { 1571 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1572 std::ostringstream stream; 1573 WideStringView str(stringWithNulls); 1574 EXPECT_EQ(2u, str.GetLength()); 1575 stream << str; 1576 EXPECT_EQ(2u, stream.tellp()); 1577 str = L""; 1578 } 1579 1580 // Writing a WideStringView with nulls but specifying its length treats it as 1581 // a C++-style string. 1582 { 1583 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1584 std::ostringstream stream; 1585 WideStringView str(stringWithNulls, 4); 1586 EXPECT_EQ(4u, str.GetLength()); 1587 stream << str; 1588 EXPECT_EQ(4u, stream.tellp()); 1589 str = L""; 1590 } 1591 1592 // << operators can be chained. 1593 { 1594 std::ostringstream stream; 1595 WideStringView str1(L"abc"); 1596 WideStringView str2(L"def"); 1597 stream << str1 << str2; 1598 EXPECT_EQ("abcdef", stream.str()); 1599 } 1600 } 1601 1602 TEST(WideStringView, WideOStreamOverload) { 1603 // Basic case, empty string 1604 { 1605 std::wostringstream stream; 1606 WideStringView str; 1607 stream << str; 1608 EXPECT_EQ(L"", stream.str()); 1609 } 1610 1611 // Basic case, non-empty string 1612 { 1613 std::wostringstream stream; 1614 WideStringView str(L"def"); 1615 stream << "abc" << str << "ghi"; 1616 EXPECT_EQ(L"abcdefghi", stream.str()); 1617 } 1618 1619 // Basic case, wide character 1620 { 1621 std::wostringstream stream; 1622 WideStringView str(L"\u20AC"); 1623 stream << str; 1624 EXPECT_EQ(L"\u20AC", stream.str()); 1625 } 1626 1627 // Changing the WideStringView does not change the stream it was written to. 1628 { 1629 std::wostringstream stream; 1630 WideStringView str(L"abc"); 1631 stream << str; 1632 str = L"123"; 1633 EXPECT_EQ(L"abc", stream.str()); 1634 } 1635 1636 // Writing it again to the stream will use the latest value. 1637 { 1638 std::wostringstream stream; 1639 WideStringView str(L"abc"); 1640 stream << str; 1641 stream.str(L""); 1642 str = L"123"; 1643 stream << str; 1644 EXPECT_EQ(L"123", stream.str()); 1645 } 1646 1647 // Writing a WideStringView with nulls and no specified length treats it as 1648 // a C-style null-terminated string. 1649 { 1650 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1651 std::wostringstream stream; 1652 WideStringView str(stringWithNulls); 1653 EXPECT_EQ(2u, str.GetLength()); 1654 stream << str; 1655 EXPECT_EQ(2u, stream.tellp()); 1656 } 1657 1658 // Writing a WideStringView with nulls but specifying its length treats it as 1659 // a C++-style string. 1660 { 1661 wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'}; 1662 std::wostringstream stream; 1663 WideStringView str(stringWithNulls, 4); 1664 EXPECT_EQ(4u, str.GetLength()); 1665 stream << str; 1666 EXPECT_EQ(4u, stream.tellp()); 1667 } 1668 1669 // << operators can be chained. 1670 { 1671 std::wostringstream stream; 1672 WideStringView str1(L"abc"); 1673 WideStringView str2(L"def"); 1674 stream << str1 << str2; 1675 EXPECT_EQ(L"abcdef", stream.str()); 1676 } 1677 } 1678 1679 } // namespace fxcrt 1680