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