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