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 13using brillo::Any; 14 15TEST(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 28TEST(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 45TEST(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 54TEST(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 97TEST(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 112TEST(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 141TEST(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 160TEST(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 186TEST(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 209TEST(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 225TEST(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 240TEST(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 254TEST(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 262TEST(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 270TEST(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 278TEST(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 286TEST(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 295TEST(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 308TEST(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