• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TEST(Any,Empty)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 
TEST(Any,SimpleTypes)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 
TEST(Any,Clear)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 
TEST(Any,Assignments)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 
TEST(Any,Enums)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 
TEST(Any,Integers)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 
TEST(Any,Pointers)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 
TEST(Any,Arrays)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 
TEST(Any,References)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 
TEST(Any,CustomTypes)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 
TEST(Any,Swap)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 
TEST(Any,TypeMismatch)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 
TEST(Any,TryGet)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 
TEST(Any,Compare_Int)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 
TEST(Any,Compare_String)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 
TEST(Any,Compare_Array)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 
TEST(Any,Compare_Empty)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 
TEST(Any,Compare_NonComparable)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 
TEST(Any,GetUndecoratedTypeName)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