xref: /aosp_15_r20/external/libbrillo/brillo/any_test.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
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