1 /* 2 * Copyright (C) 2016 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 "gtest/gtest.h" 18 19 #include "chre/util/dynamic_vector.h" 20 #include "chre/util/macros.h" 21 22 #include <stdint.h> 23 24 using chre::DynamicVector; 25 26 namespace { 27 constexpr int kMaxTestCapacity = 10; 28 int gDestructorCount[kMaxTestCapacity]; 29 30 class Dummy { 31 public: 32 ~Dummy() { 33 if (mValue >= 0) { 34 gDestructorCount[mValue]++; 35 } 36 }; 37 void setValue(int value) { 38 mValue = value; 39 } 40 int getValue() { 41 return mValue; 42 } 43 44 private: 45 int mValue = -1; 46 }; 47 48 void resetDestructorCounts() { 49 for (size_t i = 0; i < ARRAY_SIZE(gDestructorCount); i++) { 50 gDestructorCount[i] = 0; 51 } 52 } 53 } // namespace 54 55 TEST(DynamicVector, EmptyByDefault) { 56 DynamicVector<int> vector; 57 EXPECT_EQ(vector.data(), nullptr); 58 EXPECT_TRUE(vector.empty()); 59 EXPECT_EQ(vector.size(), 0); 60 EXPECT_EQ(vector.capacity(), 0); 61 vector.clear(); 62 } 63 64 TEST(DynamicVector, PushBackAndRead) { 65 DynamicVector<int> vector; 66 ASSERT_TRUE(vector.push_back(0x1337)); 67 EXPECT_EQ(vector.size(), 1); 68 EXPECT_EQ(vector.capacity(), 1); 69 EXPECT_EQ(vector.data(), &vector[0]); 70 EXPECT_FALSE(vector.empty()); 71 EXPECT_EQ(vector[0], 0x1337); 72 } 73 74 TEST(DynamicVector, PushBackReserveAndReadTrivialType) { 75 DynamicVector<int> vector; 76 ASSERT_TRUE(vector.emplace_back(0x1337)); 77 ASSERT_TRUE(vector.push_back(0xface)); 78 int x = 0xcafe; 79 ASSERT_TRUE(vector.push_back(std::move(x))); 80 ASSERT_TRUE(vector.insert(vector.size(), 0xd00d)); 81 EXPECT_EQ(vector.size(), 4); 82 EXPECT_EQ(vector.capacity(), 4); 83 EXPECT_EQ(vector[0], 0x1337); 84 EXPECT_EQ(vector[1], 0xface); 85 EXPECT_EQ(vector[2], 0xcafe); 86 EXPECT_EQ(vector[3], 0xd00d); 87 88 ASSERT_TRUE(vector.reserve(8)); 89 EXPECT_EQ(vector.size(), 4); 90 EXPECT_EQ(vector.capacity(), 8); 91 EXPECT_EQ(vector[0], 0x1337); 92 EXPECT_EQ(vector[1], 0xface); 93 EXPECT_EQ(vector[2], 0xcafe); 94 EXPECT_EQ(vector[3], 0xd00d); 95 } 96 97 TEST(DynamicVector, CompareEqual) { 98 DynamicVector<int> lhs; 99 ASSERT_TRUE(lhs.push_back(0x1337)); 100 ASSERT_TRUE(lhs.push_back(0xface)); 101 DynamicVector<int> rhs; 102 ASSERT_TRUE(rhs.push_back(0x1337)); 103 ASSERT_TRUE(rhs.push_back(0xface)); 104 105 ASSERT_EQ(lhs, rhs); // equal vectors 106 107 ASSERT_TRUE(lhs.push_back(0xb00c)); 108 ASSERT_FALSE(lhs == rhs); // different size 109 110 ASSERT_TRUE(rhs.push_back(0xc00b)); 111 ASSERT_FALSE(lhs == rhs); // equal size different elements 112 } 113 114 constexpr int kConstructedMagic = 0xdeadbeef; 115 116 class MovableButNonCopyable : public chre::NonCopyable { 117 public: 118 MovableButNonCopyable(int value) : mValue(value) {} 119 120 MovableButNonCopyable(MovableButNonCopyable &&other) { 121 mValue = other.mValue; 122 other.mValue = -1; 123 } 124 125 MovableButNonCopyable &operator=(MovableButNonCopyable &&other) { 126 assert(mMagic == kConstructedMagic); 127 mValue = other.mValue; 128 other.mValue = -1; 129 return *this; 130 } 131 132 int getValue() const { 133 return mValue; 134 } 135 136 private: 137 int mMagic = kConstructedMagic; 138 int mValue; 139 }; 140 141 TEST(DynamicVector, PushBackReserveAndReadMovableButNonCopyable) { 142 DynamicVector<MovableButNonCopyable> vector; 143 ASSERT_TRUE(vector.emplace_back(0x1337)); 144 ASSERT_TRUE(vector.emplace_back(0xface)); 145 MovableButNonCopyable mbnc(0xcafe); 146 ASSERT_TRUE(vector.push_back(std::move(mbnc))); 147 EXPECT_EQ(mbnc.getValue(), -1); 148 MovableButNonCopyable mbnc2(0xd00d); 149 ASSERT_TRUE(vector.insert(vector.size(), std::move(mbnc2))); 150 EXPECT_EQ(mbnc2.getValue(), -1); 151 152 ASSERT_TRUE(vector.reserve(8)); 153 EXPECT_EQ(vector[0].getValue(), 0x1337); 154 EXPECT_EQ(vector[1].getValue(), 0xface); 155 EXPECT_EQ(vector[2].getValue(), 0xcafe); 156 EXPECT_EQ(vector[3].getValue(), 0xd00d); 157 EXPECT_EQ(vector.size(), 4); 158 EXPECT_EQ(vector.capacity(), 8); 159 } 160 161 class CopyableButNonMovable { 162 public: 163 CopyableButNonMovable(int value) : mValue(value) {} 164 165 CopyableButNonMovable(const CopyableButNonMovable &other) { 166 mValue = other.mValue; 167 } 168 169 CopyableButNonMovable &operator=(const CopyableButNonMovable &other) { 170 assert(mMagic == kConstructedMagic); 171 mValue = other.mValue; 172 return *this; 173 } 174 175 CopyableButNonMovable(CopyableButNonMovable &&other) = delete; 176 CopyableButNonMovable &operator=(CopyableButNonMovable &&other) = delete; 177 178 int getValue() const { 179 return mValue; 180 } 181 182 private: 183 int mMagic = kConstructedMagic; 184 int mValue; 185 }; 186 187 TEST(DynamicVector, PushBackReserveAndReadCopyableButNonMovable) { 188 DynamicVector<CopyableButNonMovable> vector; 189 ASSERT_TRUE(vector.emplace_back(0x1337)); 190 ASSERT_TRUE(vector.emplace_back(0xface)); 191 CopyableButNonMovable cbnm(0xcafe); 192 ASSERT_TRUE(vector.push_back(cbnm)); 193 CopyableButNonMovable cbnm2(0xd00d); 194 ASSERT_TRUE(vector.insert(vector.size(), cbnm2)); 195 196 ASSERT_TRUE(vector.reserve(8)); 197 EXPECT_EQ(vector[0].getValue(), 0x1337); 198 EXPECT_EQ(vector[1].getValue(), 0xface); 199 EXPECT_EQ(vector[2].getValue(), 0xcafe); 200 EXPECT_EQ(vector[3].getValue(), 0xd00d); 201 EXPECT_EQ(vector.size(), 4); 202 EXPECT_EQ(vector.capacity(), 8); 203 } 204 205 class MovableAndCopyable { 206 public: 207 MovableAndCopyable(int value) : mValue(value) {} 208 209 MovableAndCopyable(const MovableAndCopyable &other) { 210 mValue = other.mValue; 211 } 212 213 MovableAndCopyable(MovableAndCopyable &&other) { 214 // The move constructor multiplies the value by 2 so that we can see that it 215 // was used 216 mValue = other.mValue * 2; 217 } 218 219 MovableAndCopyable &operator=(const MovableAndCopyable &other) { 220 assert(mMagic == kConstructedMagic); 221 mValue = other.mValue; 222 return *this; 223 } 224 225 MovableAndCopyable &operator=(MovableAndCopyable &&other) { 226 assert(mMagic == kConstructedMagic); 227 mValue = other.mValue * 2; 228 other.mValue = -1; 229 return *this; 230 } 231 232 int getValue() const { 233 return mValue; 234 } 235 236 private: 237 int mMagic = kConstructedMagic; 238 int mValue; 239 }; 240 241 TEST(DynamicVector, ReservePrefersMove) { 242 // Ensure that preference is given to std::move in reserve() 243 DynamicVector<MovableAndCopyable> vector; 244 245 // Reserve enough space for the first two elements. 246 ASSERT_TRUE(vector.reserve(2)); 247 ASSERT_TRUE(vector.emplace_back(1000)); 248 ASSERT_TRUE(vector.emplace_back(2000)); 249 250 // Reserve more than enough space causing a move to be required. 251 ASSERT_TRUE(vector.reserve(4)); 252 253 // Move on this type results in a multiplication by 2. Verify that all 254 // elements have been multiplied by 2. 255 EXPECT_EQ(vector[0].getValue(), 2000); 256 EXPECT_EQ(vector[1].getValue(), 4000); 257 } 258 259 /** 260 * A simple test helper object to count number of construction and destructions. 261 */ 262 class Foo { 263 public: 264 /** 265 * Construct an object storing a simple integer. Increment the number of 266 * objects that have been constructed of this type. 267 */ 268 Foo(int value) : value(value) { 269 sConstructedCounter++; 270 } 271 272 Foo(const Foo &other) { 273 value = other.value; 274 sConstructedCounter++; 275 } 276 277 Foo(Foo &&other) = delete; 278 279 /** 280 * Tear down the object, decrementing the number of objects that have been 281 * constructed of this type. 282 */ 283 ~Foo() { 284 sConstructedCounter--; 285 } 286 287 //! The number of objects of this type that have been constructed. 288 static ssize_t sConstructedCounter; 289 290 //! The value stored in the object to verify the contents of this object after 291 //! construction. 292 int value; 293 }; 294 295 //! Storage for the Foo reference counter. 296 ssize_t Foo::sConstructedCounter = 0; 297 298 TEST(DynamicVector, EmplaceBackAndDestruct) { 299 Foo::sConstructedCounter = 0; 300 { 301 DynamicVector<Foo> vector; 302 ASSERT_TRUE(vector.emplace_back(1000)); 303 ASSERT_TRUE(vector.emplace_back(2000)); 304 ASSERT_TRUE(vector.emplace_back(3000)); 305 ASSERT_TRUE(vector.emplace_back(4000)); 306 307 ASSERT_EQ(vector[0].value, 1000); 308 ASSERT_EQ(vector[1].value, 2000); 309 ASSERT_EQ(vector[2].value, 3000); 310 ASSERT_EQ(vector[3].value, 4000); 311 312 EXPECT_EQ(Foo::sConstructedCounter, 4); 313 } 314 315 EXPECT_EQ(Foo::sConstructedCounter, 0); 316 } 317 318 TEST(DynamicVector, InsertEmpty) { 319 DynamicVector<int> vector; 320 EXPECT_CHRE_ASSERT(EXPECT_FALSE(vector.insert(1, 0x1337))); 321 322 // Insert to empty vector 323 ASSERT_TRUE(vector.insert(0, 0x1337)); 324 EXPECT_EQ(vector[0], 0x1337); 325 326 // Insert at end triggering grow 327 ASSERT_EQ(vector.capacity(), 1); 328 EXPECT_TRUE(vector.insert(1, 0xface)); 329 EXPECT_EQ(vector[0], 0x1337); 330 EXPECT_EQ(vector[1], 0xface); 331 332 // Insert at beginning triggering grow 333 ASSERT_EQ(vector.capacity(), 2); 334 EXPECT_TRUE(vector.insert(0, 0xcafe)); 335 EXPECT_EQ(vector[0], 0xcafe); 336 EXPECT_EQ(vector[1], 0x1337); 337 EXPECT_EQ(vector[2], 0xface); 338 339 // Insert at middle with spare capacity 340 ASSERT_EQ(vector.capacity(), 4); 341 EXPECT_TRUE(vector.insert(1, 0xdead)); 342 EXPECT_EQ(vector[0], 0xcafe); 343 EXPECT_EQ(vector[1], 0xdead); 344 EXPECT_EQ(vector[2], 0x1337); 345 EXPECT_EQ(vector[3], 0xface); 346 347 // Insert at middle triggering grow 348 ASSERT_EQ(vector.capacity(), 4); 349 EXPECT_TRUE(vector.insert(2, 0xbeef)); 350 EXPECT_EQ(vector[0], 0xcafe); 351 EXPECT_EQ(vector[1], 0xdead); 352 EXPECT_EQ(vector[2], 0xbeef); 353 EXPECT_EQ(vector[3], 0x1337); 354 EXPECT_EQ(vector[4], 0xface); 355 356 // Insert at beginning with spare capacity 357 ASSERT_EQ(vector.capacity(), 8); 358 ASSERT_EQ(vector.size(), 5); 359 EXPECT_TRUE(vector.insert(0, 0xabad)); 360 EXPECT_EQ(vector[0], 0xabad); 361 EXPECT_EQ(vector[1], 0xcafe); 362 EXPECT_EQ(vector[2], 0xdead); 363 EXPECT_EQ(vector[3], 0xbeef); 364 EXPECT_EQ(vector[4], 0x1337); 365 EXPECT_EQ(vector[5], 0xface); 366 367 // Insert at end with spare capacity 368 ASSERT_EQ(vector.size(), 6); 369 EXPECT_TRUE(vector.insert(vector.size(), 0xc0de)); 370 EXPECT_EQ(vector[0], 0xabad); 371 EXPECT_EQ(vector[1], 0xcafe); 372 EXPECT_EQ(vector[2], 0xdead); 373 EXPECT_EQ(vector[3], 0xbeef); 374 EXPECT_EQ(vector[4], 0x1337); 375 EXPECT_EQ(vector[5], 0xface); 376 EXPECT_EQ(vector[6], 0xc0de); 377 } 378 379 TEST(DynamicVector, PushBackInsertInMiddleAndRead) { 380 DynamicVector<int> vector; 381 ASSERT_TRUE(vector.push_back(0x1337)); 382 ASSERT_TRUE(vector.push_back(0xface)); 383 ASSERT_TRUE(vector.push_back(0xcafe)); 384 ASSERT_TRUE(vector.insert(1, 0xbeef)); 385 386 ASSERT_EQ(vector[0], 0x1337); 387 ASSERT_EQ(vector[1], 0xbeef); 388 ASSERT_EQ(vector[2], 0xface); 389 ASSERT_EQ(vector[3], 0xcafe); 390 } 391 392 TEST(DynamicVector, PushBackAndErase) { 393 DynamicVector<int> vector; 394 ASSERT_TRUE(vector.push_back(0x1337)); 395 ASSERT_TRUE(vector.push_back(0xcafe)); 396 ASSERT_TRUE(vector.push_back(0xbeef)); 397 ASSERT_TRUE(vector.push_back(0xface)); 398 399 vector.erase(1); 400 401 ASSERT_EQ(vector[0], 0x1337); 402 ASSERT_EQ(vector[1], 0xbeef); 403 ASSERT_EQ(vector[2], 0xface); 404 ASSERT_EQ(vector.size(), 3); 405 } 406 407 TEST(DynamicVector, FindEmpty) { 408 DynamicVector<int> vector; 409 ASSERT_EQ(vector.find(0), 0); 410 } 411 412 TEST(DynamicVector, FindWithElements) { 413 DynamicVector<int> vector; 414 ASSERT_TRUE(vector.push_back(0x1337)); 415 ASSERT_TRUE(vector.push_back(0xcafe)); 416 ASSERT_TRUE(vector.push_back(0xbeef)); 417 418 ASSERT_EQ(vector.find(0x1337), 0); 419 ASSERT_EQ(vector.find(0xcafe), 1); 420 ASSERT_EQ(vector.find(0xbeef), 2); 421 ASSERT_EQ(vector.find(1000), 3); 422 } 423 424 TEST(DynamicVector, EraseDestructorCalled) { 425 resetDestructorCounts(); 426 427 DynamicVector<Dummy> vector; 428 vector.reserve(4); 429 for (size_t i = 0; i < 4; ++i) { 430 vector.emplace_back(); 431 vector[i].setValue(i); 432 } 433 434 // last item before erase is '3'. 435 vector.erase(1); 436 EXPECT_EQ(0, gDestructorCount[0]); 437 EXPECT_EQ(0, gDestructorCount[1]); 438 EXPECT_EQ(0, gDestructorCount[2]); 439 EXPECT_EQ(1, gDestructorCount[3]); 440 441 // last item before erase is still '3'. 442 vector.erase(2); 443 EXPECT_EQ(0, gDestructorCount[0]); 444 EXPECT_EQ(0, gDestructorCount[1]); 445 EXPECT_EQ(0, gDestructorCount[2]); 446 EXPECT_EQ(2, gDestructorCount[3]); 447 448 // last item before erase is now '2'. 449 vector.erase(0); 450 EXPECT_EQ(0, gDestructorCount[0]); 451 EXPECT_EQ(0, gDestructorCount[1]); 452 EXPECT_EQ(1, gDestructorCount[2]); 453 EXPECT_EQ(2, gDestructorCount[3]); 454 } 455 456 TEST(DynamicVector, Clear) { 457 resetDestructorCounts(); 458 459 DynamicVector<Dummy> vector; 460 vector.reserve(4); 461 for (size_t i = 0; i < 4; ++i) { 462 vector.emplace_back(); 463 vector[i].setValue(i); 464 } 465 466 vector.clear(); 467 EXPECT_EQ(vector.size(), 0); 468 EXPECT_EQ(vector.capacity(), 4); 469 470 for (size_t i = 0; i < 4; ++i) { 471 EXPECT_EQ(gDestructorCount[i], 1); 472 } 473 } 474 475 TEST(DynamicVectorDeathTest, SwapWithInvalidIndex) { 476 DynamicVector<int> vector; 477 vector.push_back(0x1337); 478 vector.push_back(0xcafe); 479 EXPECT_DEATH(vector.swap(0, 2), ""); 480 } 481 482 TEST(DynamicVectorDeathTest, SwapWithInvalidIndices) { 483 DynamicVector<int> vector; 484 vector.push_back(0x1337); 485 vector.push_back(0xcafe); 486 EXPECT_DEATH(vector.swap(2, 3), ""); 487 } 488 489 TEST(DynamicVector, Swap) { 490 DynamicVector<int> vector; 491 vector.push_back(0x1337); 492 vector.push_back(0xcafe); 493 494 vector.swap(0, 1); 495 EXPECT_EQ(vector[0], 0xcafe); 496 EXPECT_EQ(vector[1], 0x1337); 497 } 498 499 TEST(DynamicVector, BackFront) { 500 DynamicVector<int> vector; 501 vector.push_back(0x1337); 502 EXPECT_EQ(vector.front(), 0x1337); 503 EXPECT_EQ(vector.back(), 0x1337); 504 vector.push_back(0xcafe); 505 EXPECT_EQ(vector.front(), 0x1337); 506 EXPECT_EQ(vector.back(), 0xcafe); 507 vector.erase(0); 508 EXPECT_EQ(vector.front(), 0xcafe); 509 EXPECT_EQ(vector.back(), 0xcafe); 510 } 511 512 TEST(DynamicVector, Iterator) { 513 DynamicVector<int> vector; 514 vector.push_back(0); 515 vector.push_back(1); 516 vector.push_back(2); 517 518 size_t index = 0; 519 for (DynamicVector<int>::iterator it = vector.begin(); it != vector.end(); 520 ++it) { 521 EXPECT_EQ(vector[index++], *it); 522 } 523 524 DynamicVector<int>::iterator it = vector.begin() + vector.size() - 1; 525 EXPECT_EQ(vector[vector.size() - 1], *it); 526 527 it = vector.begin() + vector.size(); 528 EXPECT_TRUE(it == vector.end()); 529 } 530 531 TEST(DynamicVector, ConstIterator) { 532 DynamicVector<int> vector; 533 vector.push_back(0); 534 vector.push_back(1); 535 vector.push_back(2); 536 537 size_t index = 0; 538 for (DynamicVector<int>::const_iterator cit = vector.cbegin(); 539 cit != vector.cend(); ++cit) { 540 EXPECT_EQ(vector[index++], *cit); 541 } 542 543 DynamicVector<int>::const_iterator cit = vector.cbegin() + vector.size() - 1; 544 EXPECT_EQ(vector[vector.size() - 1], *cit); 545 546 cit = vector.cbegin() + vector.size(); 547 EXPECT_TRUE(cit == vector.cend()); 548 } 549 550 TEST(DynamicVector, IteratorAndPushBack) { 551 DynamicVector<int> vector; 552 vector.push_back(0); 553 vector.push_back(1); 554 vector.push_back(2); 555 size_t oldCapacity = vector.capacity(); 556 557 DynamicVector<int>::iterator it_b = vector.begin(); 558 DynamicVector<int>::iterator it_e = vector.end(); 559 560 vector.push_back(3); 561 ASSERT_TRUE(oldCapacity == vector.capacity()); 562 563 size_t index = 0; 564 for (; it_b != it_e; ++it_b) { 565 EXPECT_EQ(vector[index++], *it_b); 566 } 567 } 568 569 TEST(DynamicVector, IteratorAndEmplaceBack) { 570 DynamicVector<int> vector; 571 vector.push_back(0); 572 vector.push_back(1); 573 vector.push_back(2); 574 size_t oldCapacity = vector.capacity(); 575 576 DynamicVector<int>::iterator it_b = vector.begin(); 577 DynamicVector<int>::iterator it_e = vector.end(); 578 579 vector.emplace_back(3); 580 ASSERT_TRUE(oldCapacity == vector.capacity()); 581 582 size_t index = 0; 583 for (; it_b != it_e; ++it_b) { 584 EXPECT_EQ(vector[index++], *it_b); 585 } 586 } 587 588 TEST(DynamicVector, IteratorAndReserve) { 589 DynamicVector<int> vector; 590 vector.push_back(0); 591 vector.push_back(1); 592 vector.push_back(2); 593 size_t oldCapacity = vector.capacity(); 594 595 DynamicVector<int>::iterator it_b = vector.begin(); 596 DynamicVector<int>::iterator it_e = vector.end(); 597 598 vector.reserve(oldCapacity); 599 ASSERT_TRUE(oldCapacity == vector.capacity()); 600 601 size_t index = 0; 602 for (; it_b != it_e; ++it_b) { 603 EXPECT_EQ(vector[index++], *it_b); 604 } 605 } 606 607 TEST(DynamicVector, IteratorAndInsert) { 608 DynamicVector<int> vector; 609 vector.push_back(0); 610 vector.push_back(1); 611 vector.push_back(2); 612 size_t oldCapacity = vector.capacity(); 613 614 DynamicVector<int>::iterator it_b = vector.begin(); 615 616 vector.insert(2, 3); 617 ASSERT_TRUE(oldCapacity == vector.capacity()); 618 619 size_t index = 0; 620 while (index < 2) { 621 EXPECT_EQ(vector[index++], *it_b++); 622 } 623 } 624 625 TEST(DynamicVector, IteratorAndErase) { 626 DynamicVector<int> vector; 627 vector.push_back(0); 628 vector.push_back(1); 629 vector.push_back(2); 630 631 DynamicVector<int>::iterator it_b = vector.begin(); 632 633 vector.erase(2); 634 635 size_t index = 0; 636 while (index < 2) { 637 EXPECT_EQ(vector[index++], *it_b++); 638 } 639 } 640 641 TEST(DynamicVector, IteratorAndSwap) { 642 DynamicVector<int> vector; 643 vector.push_back(0); 644 vector.push_back(1); 645 vector.push_back(2); 646 vector.push_back(3); 647 648 DynamicVector<int>::iterator it_b = vector.begin(); 649 650 vector.swap(1, 3); 651 652 size_t index = 0; 653 while (index < 4) { 654 if (index != 1 && index != 3) { 655 EXPECT_EQ(vector[index], *it_b); 656 } 657 index++; 658 it_b++; 659 } 660 } 661 662 TEST(DynamicVector, MoveConstruct) { 663 DynamicVector<int> vector; 664 ASSERT_TRUE(vector.push_back(0)); 665 ASSERT_TRUE(vector.push_back(1)); 666 ASSERT_TRUE(vector.push_back(2)); 667 668 DynamicVector<int> movedVector(std::move(vector)); 669 EXPECT_EQ(vector.data(), nullptr); 670 EXPECT_NE(movedVector.data(), nullptr); 671 EXPECT_EQ(vector.size(), 0); 672 EXPECT_EQ(movedVector.size(), 3); 673 EXPECT_EQ(vector.capacity(), 0); 674 EXPECT_EQ(movedVector.capacity(), 4); 675 } 676 677 TEST(DynamicVector, MoveAssignmentConstruct) { 678 DynamicVector<int> vector; 679 ASSERT_TRUE(vector.push_back(0)); 680 ASSERT_TRUE(vector.push_back(1)); 681 ASSERT_TRUE(vector.push_back(2)); 682 683 DynamicVector<int> movedVector; 684 movedVector = std::move(vector); 685 EXPECT_EQ(vector.data(), nullptr); 686 EXPECT_NE(movedVector.data(), nullptr); 687 EXPECT_EQ(vector.size(), 0); 688 EXPECT_EQ(movedVector.size(), 3); 689 EXPECT_EQ(vector.capacity(), 0); 690 EXPECT_EQ(movedVector.capacity(), 4); 691 } 692 693 TEST(DynamicVector, PrepareForPush) { 694 DynamicVector<int> vector; 695 EXPECT_EQ(vector.size(), 0); 696 EXPECT_EQ(vector.capacity(), 0); 697 698 // Perform an initial prepareForPush operation which causes a size of one. 699 ASSERT_TRUE(vector.prepareForPush()); 700 EXPECT_EQ(vector.size(), 0); 701 EXPECT_EQ(vector.capacity(), 1); 702 ASSERT_TRUE(vector.push_back(0xcafe)); 703 EXPECT_EQ(vector.size(), 1); 704 EXPECT_EQ(vector.capacity(), 1); 705 706 // Verify that it becomes larger 707 ASSERT_TRUE(vector.prepareForPush()); 708 EXPECT_EQ(vector[0], 0xcafe); 709 EXPECT_EQ(vector.size(), 1); 710 EXPECT_EQ(vector.capacity(), 2); 711 712 // The vector should not become any larger than necessary. 713 ASSERT_TRUE(vector.prepareForPush()); 714 EXPECT_EQ(vector[0], 0xcafe); 715 EXPECT_EQ(vector.size(), 1); 716 EXPECT_EQ(vector.capacity(), 2); 717 } 718 719 // TODO: Add a test for when memory allocation returns nullptr. 720 721 TEST(DynamicVector, PopBack) { 722 DynamicVector<int> vector; 723 constexpr size_t kSize = 4; 724 for (int i = 0; i < kSize; i++) { 725 vector.push_back(i); 726 } 727 728 for (int i = kSize - 1; i >= 0; i--) { 729 EXPECT_EQ(vector.back(), i); 730 vector.pop_back(); 731 } 732 EXPECT_TRUE(vector.empty()); 733 } 734 735 /** 736 * A test class to default construct an integer with an incrementing value. 737 */ 738 struct FancyInt { 739 static int index; 740 int value; 741 742 FancyInt() : value(index++) {} 743 }; 744 745 int FancyInt::index = 0; 746 747 TEST(DynamicVector, Resize) { 748 DynamicVector<FancyInt> vector; 749 ASSERT_TRUE(vector.resize(4)); 750 ASSERT_EQ(vector.size(), 4); 751 752 EXPECT_EQ(vector[0].value, 0); 753 EXPECT_EQ(vector[1].value, 1); 754 EXPECT_EQ(vector[2].value, 2); 755 EXPECT_EQ(vector[3].value, 3); 756 757 ASSERT_TRUE(vector.resize(2)); 758 ASSERT_EQ(vector.size(), 2); 759 760 EXPECT_EQ(vector[0].value, 0); 761 EXPECT_EQ(vector[1].value, 1); 762 763 ASSERT_TRUE(vector.resize(4)); 764 ASSERT_EQ(vector.size(), 4); 765 766 EXPECT_EQ(vector[0].value, 0); 767 EXPECT_EQ(vector[1].value, 1); 768 EXPECT_EQ(vector[2].value, 4); 769 EXPECT_EQ(vector[3].value, 5); 770 771 // Reset index for future tests 772 FancyInt::index = 0; 773 }