Home | History | Annotate | Download | only in brillo
      1 // Copyright 2014 The Chromium OS 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 <string>
      6 
      7 #include <brillo/any.h>
      8 #include <gtest/gtest.h>
      9 
     10 using brillo::internal_details::Buffer;
     11 using brillo::GetTypeTag;
     12 
     13 TEST(Buffer, Empty) {
     14   Buffer buffer;
     15   EXPECT_TRUE(buffer.IsEmpty());
     16   EXPECT_EQ(Buffer::kExternal, buffer.storage_);
     17   EXPECT_EQ(nullptr, buffer.GetDataPtr());
     18 }
     19 
     20 TEST(Buffer, Store_Int) {
     21   Buffer buffer;
     22   buffer.Assign(2);
     23   EXPECT_FALSE(buffer.IsEmpty());
     24   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     25   EXPECT_STREQ(GetTypeTag<int>(), buffer.GetDataPtr()->GetTypeTag());
     26 }
     27 
     28 TEST(Buffer, Store_Double) {
     29   Buffer buffer;
     30   buffer.Assign(2.3);
     31   EXPECT_FALSE(buffer.IsEmpty());
     32   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     33   EXPECT_STREQ(GetTypeTag<double>(), buffer.GetDataPtr()->GetTypeTag());
     34 }
     35 
     36 TEST(Buffer, Store_Pointers) {
     37   Buffer buffer;
     38   // nullptr
     39   buffer.Assign(nullptr);
     40   EXPECT_FALSE(buffer.IsEmpty());
     41   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     42   EXPECT_STREQ(GetTypeTag<std::nullptr_t>(),
     43                buffer.GetDataPtr()->GetTypeTag());
     44 
     45   // char *
     46   buffer.Assign("abcd");
     47   EXPECT_FALSE(buffer.IsEmpty());
     48   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     49   EXPECT_STREQ(GetTypeTag<const char*>(), buffer.GetDataPtr()->GetTypeTag());
     50 
     51   // pointer to non-trivial object
     52   class NonTrivial {
     53    public:
     54     virtual ~NonTrivial() {}
     55   } non_trivial;
     56   buffer.Assign(&non_trivial);
     57   EXPECT_FALSE(buffer.IsEmpty());
     58   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     59   EXPECT_STREQ(GetTypeTag<NonTrivial*>(), buffer.GetDataPtr()->GetTypeTag());
     60 }
     61 
     62 TEST(Buffer, Store_NonTrivialObjects) {
     63   class NonTrivial {
     64    public:
     65     virtual ~NonTrivial() {}
     66   } non_trivial;
     67   Buffer buffer;
     68   buffer.Assign(non_trivial);
     69   EXPECT_FALSE(buffer.IsEmpty());
     70   EXPECT_EQ(Buffer::kExternal, buffer.storage_);
     71   EXPECT_STREQ(GetTypeTag<NonTrivial>(), buffer.GetDataPtr()->GetTypeTag());
     72 }
     73 
     74 TEST(Buffer, Store_Objects) {
     75   Buffer buffer;
     76 
     77   struct Small {
     78     double d;
     79   } small = {};
     80   buffer.Assign(small);
     81   EXPECT_FALSE(buffer.IsEmpty());
     82   EXPECT_EQ(Buffer::kContained, buffer.storage_);
     83   EXPECT_STREQ(GetTypeTag<Small>(), buffer.GetDataPtr()->GetTypeTag());
     84 
     85   struct Large {
     86     char c[20];
     87   } large = {};
     88   buffer.Assign(large);
     89   EXPECT_FALSE(buffer.IsEmpty());
     90   EXPECT_EQ(Buffer::kExternal, buffer.storage_);
     91   EXPECT_STREQ(GetTypeTag<Large>(), buffer.GetDataPtr()->GetTypeTag());
     92 }
     93 
     94 TEST(Buffer, Copy) {
     95   Buffer buffer1;
     96   Buffer buffer2;
     97 
     98   buffer1.Assign(30);
     99   buffer1.CopyTo(&buffer2);
    100   EXPECT_FALSE(buffer1.IsEmpty());
    101   EXPECT_FALSE(buffer2.IsEmpty());
    102   EXPECT_STREQ(GetTypeTag<int>(), buffer1.GetDataPtr()->GetTypeTag());
    103   EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag());
    104   EXPECT_EQ(30, buffer1.GetData<int>());
    105   EXPECT_EQ(30, buffer2.GetData<int>());
    106 
    107   buffer1.Assign(std::string("abc"));
    108   buffer1.CopyTo(&buffer2);
    109   EXPECT_FALSE(buffer1.IsEmpty());
    110   EXPECT_FALSE(buffer2.IsEmpty());
    111   EXPECT_STREQ(GetTypeTag<std::string>(), buffer1.GetDataPtr()->GetTypeTag());
    112   EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag());
    113   EXPECT_EQ("abc", buffer1.GetData<std::string>());
    114   EXPECT_EQ("abc", buffer2.GetData<std::string>());
    115 }
    116 
    117 TEST(Buffer, Move) {
    118   // Move operations essentially leave the source object in a state that is
    119   // guaranteed to be safe for reuse or destruction. There is no other explicit
    120   // guarantees on the exact state of the source after move (e.g. that the
    121   // source Any will be Empty after the move is complete).
    122   Buffer buffer1;
    123   Buffer buffer2;
    124 
    125   buffer1.Assign(30);
    126   buffer1.MoveTo(&buffer2);
    127   // Contained types aren't flushed, so the source Any doesn't become empty.
    128   // The contained value is just moved, but for scalars this just copies
    129   // the data and any retains the actual type.
    130   EXPECT_FALSE(buffer1.IsEmpty());
    131   EXPECT_FALSE(buffer2.IsEmpty());
    132   EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag());
    133   EXPECT_EQ(30, buffer2.GetData<int>());
    134 
    135   buffer1.Assign(std::string("abc"));
    136   buffer1.MoveTo(&buffer2);
    137   // External types are moved by just moving the pointer value from src to dest.
    138   // This will make the source object effectively "Empty".
    139   EXPECT_TRUE(buffer1.IsEmpty());
    140   EXPECT_FALSE(buffer2.IsEmpty());
    141   EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag());
    142   EXPECT_EQ("abc", buffer2.GetData<std::string>());
    143 }
    144