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 <algorithm>
      6 #include <functional>
      7 #include <string>
      8 #include <vector>
      9 
     10 #include <brillo/any.h>
     11 #include <gtest/gtest.h>
     12 
     13 using brillo::Any;
     14 
     15 TEST(Any, Empty) {
     16   Any val;
     17   EXPECT_TRUE(val.IsEmpty());
     18 
     19   Any val2 = val;
     20   EXPECT_TRUE(val.IsEmpty());
     21   EXPECT_TRUE(val2.IsEmpty());
     22 
     23   Any val3 = std::move(val);
     24   EXPECT_TRUE(val.IsEmpty());
     25   EXPECT_TRUE(val3.IsEmpty());
     26 }
     27 
     28 TEST(Any, SimpleTypes) {
     29   Any val(20);
     30   EXPECT_FALSE(val.IsEmpty());
     31   EXPECT_TRUE(val.IsTypeCompatible<int>());
     32   EXPECT_EQ(20, val.Get<int>());
     33 
     34   Any val2(3.1415926);
     35   EXPECT_FALSE(val2.IsEmpty());
     36   EXPECT_TRUE(val2.IsTypeCompatible<double>());
     37   EXPECT_FALSE(val2.IsTypeCompatible<int>());
     38   EXPECT_DOUBLE_EQ(3.1415926, val2.Get<double>());
     39 
     40   Any val3(std::string("blah"));
     41   EXPECT_TRUE(val3.IsTypeCompatible<std::string>());
     42   EXPECT_EQ("blah", val3.Get<std::string>());
     43 }
     44 
     45 TEST(Any, Clear) {
     46   Any val('x');
     47   EXPECT_FALSE(val.IsEmpty());
     48   EXPECT_EQ('x', val.Get<char>());
     49 
     50   val.Clear();
     51   EXPECT_TRUE(val.IsEmpty());
     52 }
     53 
     54 TEST(Any, Assignments) {
     55   Any val(20);
     56   EXPECT_EQ(20, val.Get<int>());
     57 
     58   val = 3.1415926;
     59   EXPECT_FALSE(val.IsEmpty());
     60   EXPECT_TRUE(val.IsTypeCompatible<double>());
     61   EXPECT_DOUBLE_EQ(3.1415926, val.Get<double>());
     62 
     63   val = std::string("blah");
     64   EXPECT_EQ("blah", val.Get<std::string>());
     65 
     66   Any val2;
     67   EXPECT_TRUE(val2.IsEmpty());
     68   val2 = val;
     69   EXPECT_FALSE(val.IsEmpty());
     70   EXPECT_FALSE(val2.IsEmpty());
     71   EXPECT_EQ("blah", val.Get<std::string>());
     72   EXPECT_EQ("blah", val2.Get<std::string>());
     73   val.Clear();
     74   EXPECT_TRUE(val.IsEmpty());
     75   EXPECT_EQ("blah", val2.Get<std::string>());
     76   val2.Clear();
     77   EXPECT_TRUE(val2.IsEmpty());
     78 
     79   val = std::vector<int>{100, 20, 3};
     80   auto v = val.Get<std::vector<int>>();
     81   EXPECT_EQ(100, v[0]);
     82   EXPECT_EQ(20, v[1]);
     83   EXPECT_EQ(3, v[2]);
     84 
     85   val2 = std::move(val);
     86   EXPECT_TRUE(val.IsEmpty());
     87   EXPECT_TRUE(val2.IsTypeCompatible<std::vector<int>>());
     88   EXPECT_EQ(3, val2.Get<std::vector<int>>().size());
     89 
     90   val = val2;
     91   EXPECT_TRUE(val.IsTypeCompatible<std::vector<int>>());
     92   EXPECT_TRUE(val2.IsTypeCompatible<std::vector<int>>());
     93   EXPECT_EQ(3, val.Get<std::vector<int>>().size());
     94   EXPECT_EQ(3, val2.Get<std::vector<int>>().size());
     95 }
     96 
     97 TEST(Any, Enums) {
     98   enum class Dummy { foo, bar, baz };
     99   Any val(Dummy::bar);
    100   EXPECT_FALSE(val.IsEmpty());
    101   EXPECT_TRUE(val.IsConvertibleToInteger());
    102   EXPECT_EQ(Dummy::bar, val.Get<Dummy>());
    103   EXPECT_EQ(1, val.GetAsInteger());
    104 
    105   val = Dummy::baz;
    106   EXPECT_EQ(2, val.GetAsInteger());
    107 
    108   val = Dummy::foo;
    109   EXPECT_EQ(0, val.GetAsInteger());
    110 }
    111 
    112 TEST(Any, Integers) {
    113   Any val(14);
    114   EXPECT_TRUE(val.IsConvertibleToInteger());
    115   EXPECT_EQ(14, val.Get<int>());
    116   EXPECT_EQ(14, val.GetAsInteger());
    117 
    118   val = '\x40';
    119   EXPECT_TRUE(val.IsConvertibleToInteger());
    120   EXPECT_EQ(64, val.Get<char>());
    121   EXPECT_EQ(64, val.GetAsInteger());
    122 
    123   val = static_cast<uint16_t>(65535);
    124   EXPECT_TRUE(val.IsConvertibleToInteger());
    125   EXPECT_EQ(65535, val.Get<uint16_t>());
    126   EXPECT_EQ(65535, val.GetAsInteger());
    127 
    128   val = static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFULL);
    129   EXPECT_TRUE(val.IsConvertibleToInteger());
    130   EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, val.Get<uint64_t>());
    131   EXPECT_EQ(-1, val.GetAsInteger());
    132 
    133   val = "abc";
    134   EXPECT_FALSE(val.IsConvertibleToInteger());
    135 
    136   int a = 5;
    137   val = &a;
    138   EXPECT_FALSE(val.IsConvertibleToInteger());
    139 }
    140 
    141 TEST(Any, Pointers) {
    142   Any val("abc");  // const char*
    143   EXPECT_FALSE(val.IsTypeCompatible<char*>());
    144   EXPECT_TRUE(val.IsTypeCompatible<const char*>());
    145   EXPECT_FALSE(val.IsTypeCompatible<volatile char*>());
    146   EXPECT_TRUE(val.IsTypeCompatible<volatile const char*>());
    147   EXPECT_STREQ("abc", val.Get<const char*>());
    148 
    149   int a = 10;
    150   val = &a;
    151   EXPECT_TRUE(val.IsTypeCompatible<int*>());
    152   EXPECT_TRUE(val.IsTypeCompatible<const int*>());
    153   EXPECT_TRUE(val.IsTypeCompatible<volatile int*>());
    154   EXPECT_TRUE(val.IsTypeCompatible<volatile const int*>());
    155   EXPECT_EQ(10, *val.Get<const int*>());
    156   *val.Get<int*>() = 3;
    157   EXPECT_EQ(3, a);
    158 }
    159 
    160 TEST(Any, Arrays) {
    161   // The following test are here to validate the array-to-pointer decay rules.
    162   // Since Any does not store the contents of a C-style array, just a pointer
    163   // to the data, putting array data into Any could be dangerous.
    164   // Make sure the array's lifetime exceeds that of an Any containing the
    165   // pointer to the array data.
    166   // If you want to store the array with data, use corresponding value types
    167   // such as std::vector or a struct containing C-style array as a member.
    168 
    169   int int_array[] = {1, 2, 3};  // int*
    170   Any val = int_array;
    171   EXPECT_TRUE(val.IsTypeCompatible<int*>());
    172   EXPECT_TRUE(val.IsTypeCompatible<const int*>());
    173   EXPECT_TRUE(val.IsTypeCompatible<int[]>());
    174   EXPECT_TRUE(val.IsTypeCompatible<const int[]>());
    175   EXPECT_EQ(3, val.Get<int*>()[2]);
    176 
    177   const int const_int_array[] = {10, 20, 30};  // const int*
    178   val = const_int_array;
    179   EXPECT_FALSE(val.IsTypeCompatible<int*>());
    180   EXPECT_TRUE(val.IsTypeCompatible<const int*>());
    181   EXPECT_FALSE(val.IsTypeCompatible<int[]>());
    182   EXPECT_TRUE(val.IsTypeCompatible<const int[]>());
    183   EXPECT_EQ(30, val.Get<const int*>()[2]);
    184 }
    185 
    186 TEST(Any, References) {
    187   // Passing references to object via Any might be error-prone or the
    188   // semantics could be unfamiliar to other developers. In many cases,
    189   // using pointers instead of references are more conventional and easier
    190   // to understand. Even though the cases of passing references are quite
    191   // explicit on both storing and retrieving ends, you might want to
    192   // use pointers instead anyway.
    193 
    194   int a = 5;
    195   Any val(std::ref(a));  // int&
    196   EXPECT_EQ(5, val.Get<std::reference_wrapper<int>>().get());
    197   val.Get<std::reference_wrapper<int>>().get() = 7;
    198   EXPECT_EQ(7, val.Get<std::reference_wrapper<int>>().get());
    199   EXPECT_EQ(7, a);
    200 
    201   Any val2(std::cref(a));  // const int&
    202   EXPECT_EQ(7, val2.Get<std::reference_wrapper<const int>>().get());
    203 
    204   a = 10;
    205   EXPECT_EQ(10, val.Get<std::reference_wrapper<int>>().get());
    206   EXPECT_EQ(10, val2.Get<std::reference_wrapper<const int>>().get());
    207 }
    208 
    209 TEST(Any, CustomTypes) {
    210   struct Person {
    211     std::string name;
    212     int age;
    213   };
    214   Any val(Person{"Jack", 40});
    215   Any val2 = val;
    216   EXPECT_EQ("Jack", val.Get<Person>().name);
    217   val.GetPtr<Person>()->name = "Joe";
    218   val.GetPtr<Person>()->age /= 2;
    219   EXPECT_EQ("Joe", val.Get<Person>().name);
    220   EXPECT_EQ(20, val.Get<Person>().age);
    221   EXPECT_EQ("Jack", val2.Get<Person>().name);
    222   EXPECT_EQ(40, val2.Get<Person>().age);
    223 }
    224 
    225 TEST(Any, Swap) {
    226   Any val(12);
    227   Any val2(2.7);
    228   EXPECT_EQ(12, val.Get<int>());
    229   EXPECT_EQ(2.7, val2.Get<double>());
    230 
    231   val.Swap(val2);
    232   EXPECT_EQ(2.7, val.Get<double>());
    233   EXPECT_EQ(12, val2.Get<int>());
    234 
    235   std::swap(val, val2);
    236   EXPECT_EQ(12, val.Get<int>());
    237   EXPECT_EQ(2.7, val2.Get<double>());
    238 }
    239 
    240 TEST(Any, TypeMismatch) {
    241   Any val(12);
    242   EXPECT_DEATH(val.Get<double>(),
    243                "Requesting value of type 'double' from variant containing "
    244                "'int'");
    245 
    246   val = std::string("123");
    247   EXPECT_DEATH(val.GetAsInteger(),
    248                "Unable to convert value of type 'std::.*' to integer");
    249 
    250   Any empty;
    251   EXPECT_DEATH(empty.GetAsInteger(), "Must not be called on an empty Any");
    252 }
    253 
    254 TEST(Any, TryGet) {
    255   Any val(12);
    256   Any empty;
    257   EXPECT_EQ("dummy", val.TryGet<std::string>("dummy"));
    258   EXPECT_EQ(12, val.TryGet<int>(17));
    259   EXPECT_EQ(17, empty.TryGet<int>(17));
    260 }
    261 
    262 TEST(Any, Compare_Int) {
    263   Any int1{12};
    264   Any int2{12};
    265   Any int3{20};
    266   EXPECT_EQ(int1, int2);
    267   EXPECT_NE(int2, int3);
    268 }
    269 
    270 TEST(Any, Compare_String) {
    271   Any str1{std::string{"foo"}};
    272   Any str2{std::string{"foo"}};
    273   Any str3{std::string{"bar"}};
    274   EXPECT_EQ(str1, str2);
    275   EXPECT_NE(str2, str3);
    276 }
    277 
    278 TEST(Any, Compare_Array) {
    279   Any vec1{std::vector<int>{1, 2}};
    280   Any vec2{std::vector<int>{1, 2}};
    281   Any vec3{std::vector<int>{1, 2, 3}};
    282   EXPECT_EQ(vec1, vec2);
    283   EXPECT_NE(vec2, vec3);
    284 }
    285 
    286 TEST(Any, Compare_Empty) {
    287   Any empty1;
    288   Any empty2;
    289   Any int1{1};
    290   EXPECT_EQ(empty1, empty2);
    291   EXPECT_NE(int1, empty1);
    292   EXPECT_NE(empty2, int1);
    293 }
    294 
    295 TEST(Any, Compare_NonComparable) {
    296   struct Person {
    297     std::string name;
    298     int age;
    299   };
    300   Any person1(Person{"Jack", 40});
    301   Any person2 = person1;
    302   Any person3(Person{"Jill", 20});
    303   EXPECT_NE(person1, person2);
    304   EXPECT_NE(person1, person3);
    305   EXPECT_NE(person2, person3);
    306 }
    307 
    308 TEST(Any, GetUndecoratedTypeName) {
    309   Any val;
    310   EXPECT_TRUE(val.GetUndecoratedTypeName().empty());
    311 
    312   val = 1;
    313   EXPECT_EQ(brillo::GetUndecoratedTypeName<int>(),
    314             val.GetUndecoratedTypeName());
    315 
    316   val = 3.1415926;
    317   EXPECT_EQ(brillo::GetUndecoratedTypeName<double>(),
    318             val.GetUndecoratedTypeName());
    319 
    320   val = std::string("blah");
    321   EXPECT_EQ(brillo::GetUndecoratedTypeName<std::string>(),
    322             val.GetUndecoratedTypeName());
    323 }
    324