Home | History | Annotate | Download | only in tests
      1 #include <cstring>
      2 
      3 #include "gtest/gtest.h"
      4 
      5 #include "chre/util/unique_ptr.h"
      6 
      7 using chre::UniquePtr;
      8 using chre::MakeUnique;
      9 using chre::MakeUniqueZeroFill;
     10 
     11 struct Value {
     12   Value(int value) : value(value) {
     13     constructionCounter++;
     14   }
     15 
     16   ~Value() {
     17     constructionCounter--;
     18   }
     19 
     20   Value& operator=(Value&& other) {
     21     value = other.value;
     22     return *this;
     23   }
     24 
     25   int value;
     26   static int constructionCounter;
     27 };
     28 
     29 int Value::constructionCounter = 0;
     30 
     31 TEST(UniquePtr, Construct) {
     32   UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe);
     33   ASSERT_FALSE(myInt.isNull());
     34   EXPECT_EQ(myInt.get()->value, 0xcafe);
     35   EXPECT_EQ(myInt->value, 0xcafe);
     36   EXPECT_EQ((*myInt).value, 0xcafe);
     37   EXPECT_EQ(myInt[0].value, 0xcafe);
     38 }
     39 
     40 struct BigArray {
     41   int x[2048];
     42 };
     43 
     44 TEST(UniquePtr, MakeUniqueZeroFill) {
     45   BigArray baseline = {};
     46   auto myArray = MakeUniqueZeroFill<BigArray>();
     47   ASSERT_FALSE(myArray.isNull());
     48   // Note that this doesn't actually test things properly, because we don't
     49   // guarantee that malloc is not already giving us zeroed out memory. To
     50   // properly do it, we could inject the allocator, but this function is simple
     51   // enough that it's not really worth the effort.
     52   EXPECT_EQ(std::memcmp(&baseline, myArray.get(), sizeof(baseline)), 0);
     53 }
     54 
     55 TEST(UniquePtr, MoveConstruct) {
     56   UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe);
     57   ASSERT_FALSE(myInt.isNull());
     58   Value *value = myInt.get();
     59 
     60   UniquePtr<Value> moved(std::move(myInt));
     61   EXPECT_EQ(moved.get(), value);
     62   EXPECT_EQ(myInt.get(), nullptr);
     63 }
     64 
     65 TEST(UniquePtr, Move) {
     66   Value::constructionCounter = 0;
     67 
     68   {
     69     UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe);
     70     ASSERT_FALSE(myInt.isNull());
     71     EXPECT_EQ(Value::constructionCounter, 1);
     72 
     73     UniquePtr<Value> myMovedInt = MakeUnique<Value>(0);
     74     ASSERT_FALSE(myMovedInt.isNull());
     75     EXPECT_EQ(Value::constructionCounter, 2);
     76     myMovedInt = std::move(myInt);
     77     ASSERT_FALSE(myMovedInt.isNull());
     78     ASSERT_TRUE(myInt.isNull());
     79     EXPECT_EQ(myMovedInt.get()->value, 0xcafe);
     80   }
     81 
     82   EXPECT_EQ(Value::constructionCounter, 0);
     83 }
     84 
     85 TEST(UniquePtr, Release) {
     86   Value::constructionCounter = 0;
     87 
     88   Value *value1, *value2;
     89   {
     90     UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe);
     91     ASSERT_FALSE(myInt.isNull());
     92     EXPECT_EQ(Value::constructionCounter, 1);
     93     value1 = myInt.get();
     94     EXPECT_NE(value1, nullptr);
     95     value2 = myInt.release();
     96     EXPECT_EQ(value1, value2);
     97     EXPECT_EQ(myInt.get(), nullptr);
     98     EXPECT_TRUE(myInt.isNull());
     99   }
    100 
    101   EXPECT_EQ(Value::constructionCounter, 1);
    102   EXPECT_EQ(value2->value, 0xcafe);
    103   value2->~Value();
    104   chre::memoryFree(value2);
    105 }
    106 
    107 TEST(UniquePtr, Reset) {
    108   Value::constructionCounter = 0;
    109 
    110   {
    111     UniquePtr<Value> myInt = MakeUnique<Value>(0xcafe);
    112     EXPECT_EQ(myInt.get()->value, 0xcafe);
    113     EXPECT_EQ(Value::constructionCounter, 1);
    114     myInt.reset(nullptr);
    115     EXPECT_EQ(myInt.get(), nullptr);
    116     EXPECT_EQ(Value::constructionCounter, 0);
    117 
    118     myInt = MakeUnique<Value>(0xcafe);
    119     UniquePtr<Value> myInt2 = MakeUnique<Value>(0xface);
    120     EXPECT_EQ(Value::constructionCounter, 2);
    121     myInt.reset(myInt2.release());
    122     EXPECT_EQ(Value::constructionCounter, 1);
    123     EXPECT_EQ(myInt.get()->value, 0xface);
    124     EXPECT_EQ(myInt2.get(), nullptr);
    125   }
    126 
    127   EXPECT_EQ(Value::constructionCounter, 0);
    128 }
    129