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