1 // Copyright 2013 The Flutter 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 "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/encodable_value.h"
6
7 #include <limits>
8
9 #include "gtest/gtest.h"
10
11 namespace flutter {
12
13 // Verifies that value.type() is |type|, and that of all the Is* methods, only
14 // the one that matches the type is true.
VerifyType(EncodableValue & value,EncodableValue::EncodableValue::Type type)15 void VerifyType(EncodableValue& value,
16 EncodableValue::EncodableValue::Type type) {
17 EXPECT_EQ(value.type(), type);
18
19 EXPECT_EQ(value.IsNull(), type == EncodableValue::Type::kNull);
20 EXPECT_EQ(value.IsBool(), type == EncodableValue::Type::kBool);
21 EXPECT_EQ(value.IsInt(), type == EncodableValue::Type::kInt);
22 EXPECT_EQ(value.IsLong(), type == EncodableValue::Type::kLong);
23 EXPECT_EQ(value.IsDouble(), type == EncodableValue::Type::kDouble);
24 EXPECT_EQ(value.IsString(), type == EncodableValue::Type::kString);
25 EXPECT_EQ(value.IsByteList(), type == EncodableValue::Type::kByteList);
26 EXPECT_EQ(value.IsIntList(), type == EncodableValue::Type::kIntList);
27 EXPECT_EQ(value.IsLongList(), type == EncodableValue::Type::kLongList);
28 EXPECT_EQ(value.IsDoubleList(), type == EncodableValue::Type::kDoubleList);
29 EXPECT_EQ(value.IsList(), type == EncodableValue::Type::kList);
30 EXPECT_EQ(value.IsMap(), type == EncodableValue::Type::kMap);
31 }
32
TEST(EncodableValueTest,Null)33 TEST(EncodableValueTest, Null) {
34 EncodableValue value;
35 VerifyType(value, EncodableValue::Type::kNull);
36 }
37
TEST(EncodableValueTest,Bool)38 TEST(EncodableValueTest, Bool) {
39 EncodableValue value(false);
40 VerifyType(value, EncodableValue::Type::kBool);
41
42 EXPECT_FALSE(value.BoolValue());
43 value = true;
44 EXPECT_TRUE(value.BoolValue());
45 }
46
TEST(EncodableValueTest,Int)47 TEST(EncodableValueTest, Int) {
48 EncodableValue value(42);
49 VerifyType(value, EncodableValue::Type::kInt);
50
51 EXPECT_EQ(value.IntValue(), 42);
52 value = std::numeric_limits<int32_t>::max();
53 EXPECT_EQ(value.IntValue(), std::numeric_limits<int32_t>::max());
54 }
55
TEST(EncodableValueTest,LongValueFromInt)56 TEST(EncodableValueTest, LongValueFromInt) {
57 EncodableValue value(std::numeric_limits<int32_t>::max());
58 EXPECT_EQ(value.LongValue(), std::numeric_limits<int32_t>::max());
59 }
60
TEST(EncodableValueTest,Long)61 TEST(EncodableValueTest, Long) {
62 EncodableValue value(INT64_C(42));
63 VerifyType(value, EncodableValue::Type::kLong);
64
65 EXPECT_EQ(value.LongValue(), 42);
66 value = std::numeric_limits<int64_t>::max();
67 EXPECT_EQ(value.LongValue(), std::numeric_limits<int64_t>::max());
68 }
69
TEST(EncodableValueTest,Double)70 TEST(EncodableValueTest, Double) {
71 EncodableValue value(3.14);
72 VerifyType(value, EncodableValue::Type::kDouble);
73
74 EXPECT_EQ(value.DoubleValue(), 3.14);
75 value = std::numeric_limits<double>::max();
76 EXPECT_EQ(value.DoubleValue(), std::numeric_limits<double>::max());
77 }
78
TEST(EncodableValueTest,String)79 TEST(EncodableValueTest, String) {
80 std::string hello("Hello, world!");
81 EncodableValue value(hello);
82 VerifyType(value, EncodableValue::Type::kString);
83
84 EXPECT_EQ(value.StringValue(), hello);
85 value = "Goodbye";
86 EXPECT_EQ(value.StringValue(), "Goodbye");
87 }
88
TEST(EncodableValueTest,UInt8List)89 TEST(EncodableValueTest, UInt8List) {
90 std::vector<uint8_t> data = {0, 2};
91 EncodableValue value(data);
92 VerifyType(value, EncodableValue::Type::kByteList);
93
94 std::vector<uint8_t>& list_value = value.ByteListValue();
95 list_value.push_back(std::numeric_limits<uint8_t>::max());
96 EXPECT_EQ(list_value[0], 0);
97 EXPECT_EQ(list_value[1], 2);
98
99 ASSERT_EQ(list_value.size(), 3u);
100 EXPECT_EQ(data.size(), 2u);
101 EXPECT_EQ(list_value[2], std::numeric_limits<uint8_t>::max());
102 }
103
TEST(EncodableValueTest,Int32List)104 TEST(EncodableValueTest, Int32List) {
105 std::vector<int32_t> data = {-10, 2};
106 EncodableValue value(data);
107 VerifyType(value, EncodableValue::Type::kIntList);
108
109 std::vector<int32_t>& list_value = value.IntListValue();
110 list_value.push_back(std::numeric_limits<int32_t>::max());
111 EXPECT_EQ(list_value[0], -10);
112 EXPECT_EQ(list_value[1], 2);
113
114 ASSERT_EQ(list_value.size(), 3u);
115 EXPECT_EQ(data.size(), 2u);
116 EXPECT_EQ(list_value[2], std::numeric_limits<int32_t>::max());
117 }
118
TEST(EncodableValueTest,Int64List)119 TEST(EncodableValueTest, Int64List) {
120 std::vector<int64_t> data = {-10, 2};
121 EncodableValue value(data);
122 VerifyType(value, EncodableValue::Type::kLongList);
123
124 std::vector<int64_t>& list_value = value.LongListValue();
125 list_value.push_back(std::numeric_limits<int64_t>::max());
126 EXPECT_EQ(list_value[0], -10);
127 EXPECT_EQ(list_value[1], 2);
128
129 ASSERT_EQ(list_value.size(), 3u);
130 EXPECT_EQ(data.size(), 2u);
131 EXPECT_EQ(list_value[2], std::numeric_limits<int64_t>::max());
132 }
133
TEST(EncodableValueTest,DoubleList)134 TEST(EncodableValueTest, DoubleList) {
135 std::vector<double> data = {-10.0, 2.0};
136 EncodableValue value(data);
137 VerifyType(value, EncodableValue::Type::kDoubleList);
138
139 std::vector<double>& list_value = value.DoubleListValue();
140 list_value.push_back(std::numeric_limits<double>::max());
141 EXPECT_EQ(list_value[0], -10.0);
142 EXPECT_EQ(list_value[1], 2.0);
143
144 ASSERT_EQ(list_value.size(), 3u);
145 EXPECT_EQ(data.size(), 2u);
146 EXPECT_EQ(list_value[2], std::numeric_limits<double>::max());
147 }
148
TEST(EncodableValueTest,List)149 TEST(EncodableValueTest, List) {
150 EncodableList encodables = {
151 EncodableValue(1),
152 EncodableValue(2.0),
153 EncodableValue("Three"),
154 };
155 EncodableValue value(encodables);
156 VerifyType(value, EncodableValue::Type::kList);
157
158 EncodableList& list_value = value.ListValue();
159 EXPECT_EQ(list_value[0].IntValue(), 1);
160 EXPECT_EQ(list_value[1].DoubleValue(), 2.0);
161 EXPECT_EQ(list_value[2].StringValue(), "Three");
162
163 // Ensure that it's a modifiable copy of the original array.
164 list_value.push_back(EncodableValue(true));
165 ASSERT_EQ(list_value.size(), 4u);
166 EXPECT_EQ(encodables.size(), 3u);
167 EXPECT_EQ(value.ListValue()[3].BoolValue(), true);
168 }
169
TEST(EncodableValueTest,Map)170 TEST(EncodableValueTest, Map) {
171 EncodableMap encodables = {
172 {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
173 {EncodableValue(1), EncodableValue(INT64_C(10000))},
174 {EncodableValue("two"), EncodableValue(7)},
175 };
176 EncodableValue value(encodables);
177 VerifyType(value, EncodableValue::Type::kMap);
178
179 EncodableMap& map_value = value.MapValue();
180 EXPECT_EQ(map_value[EncodableValue()].IsIntList(), true);
181 EXPECT_EQ(map_value[EncodableValue(1)].LongValue(), INT64_C(10000));
182 EXPECT_EQ(map_value[EncodableValue("two")].IntValue(), 7);
183
184 // Ensure that it's a modifiable copy of the original map.
185 map_value[EncodableValue(true)] = EncodableValue(false);
186 ASSERT_EQ(map_value.size(), 4u);
187 EXPECT_EQ(encodables.size(), 3u);
188 EXPECT_EQ(map_value[EncodableValue(true)].BoolValue(), false);
189 }
190
TEST(EncodableValueTest,EmptyTypeConstructor)191 TEST(EncodableValueTest, EmptyTypeConstructor) {
192 EXPECT_TRUE(EncodableValue(EncodableValue::Type::kNull).IsNull());
193 EXPECT_EQ(EncodableValue(EncodableValue::Type::kBool).BoolValue(), false);
194 EXPECT_EQ(EncodableValue(EncodableValue::Type::kInt).IntValue(), 0);
195 EXPECT_EQ(EncodableValue(EncodableValue::Type::kLong).LongValue(),
196 INT64_C(0));
197 EXPECT_EQ(EncodableValue(EncodableValue::Type::kDouble).DoubleValue(), 0.0);
198 EXPECT_EQ(EncodableValue(EncodableValue::Type::kString).StringValue().size(),
199 0u);
200 EXPECT_EQ(
201 EncodableValue(EncodableValue::Type::kByteList).ByteListValue().size(),
202 0u);
203 EXPECT_EQ(
204 EncodableValue(EncodableValue::Type::kIntList).IntListValue().size(), 0u);
205 EXPECT_EQ(
206 EncodableValue(EncodableValue::Type::kLongList).LongListValue().size(),
207 0u);
208 EXPECT_EQ(EncodableValue(EncodableValue::Type::kDoubleList)
209 .DoubleListValue()
210 .size(),
211 0u);
212 EXPECT_EQ(EncodableValue(EncodableValue::Type::kList).ListValue().size(), 0u);
213 EXPECT_EQ(EncodableValue(EncodableValue::Type::kMap).MapValue().size(), 0u);
214 }
215
216 // Tests that the < operator meets the requirements of using EncodableValue as
217 // a map key.
TEST(EncodableValueTest,Comparison)218 TEST(EncodableValueTest, Comparison) {
219 EncodableList values = {
220 // Null
221 EncodableValue(),
222 // Bool
223 EncodableValue(true),
224 EncodableValue(false),
225 // Int
226 EncodableValue(-7),
227 EncodableValue(0),
228 EncodableValue(100),
229 // Long
230 EncodableValue(INT64_C(-7)),
231 EncodableValue(INT64_C(0)),
232 EncodableValue(INT64_C(100)),
233 // Double
234 EncodableValue(-7.0),
235 EncodableValue(0.0),
236 EncodableValue(100.0),
237 // String
238 EncodableValue("one"),
239 EncodableValue("two"),
240 // ByteList
241 EncodableValue(std::vector<uint8_t>{0, 1}),
242 EncodableValue(std::vector<uint8_t>{0, 10}),
243 // IntList
244 EncodableValue(std::vector<int32_t>{0, 1}),
245 EncodableValue(std::vector<int32_t>{0, 100}),
246 // LongList
247 EncodableValue(std::vector<int64_t>{0, INT64_C(1)}),
248 EncodableValue(std::vector<int64_t>{0, INT64_C(100)}),
249 // DoubleList
250 EncodableValue(std::vector<int64_t>{0, INT64_C(1)}),
251 EncodableValue(std::vector<int64_t>{0, INT64_C(100)}),
252 // List
253 EncodableValue(EncodableList{EncodableValue(), EncodableValue(true)}),
254 EncodableValue(EncodableList{EncodableValue(), EncodableValue(1.0)}),
255 // Map
256 EncodableValue(EncodableMap{{EncodableValue(), EncodableValue(true)},
257 {EncodableValue(7), EncodableValue(7.0)}}),
258 EncodableValue(
259 EncodableMap{{EncodableValue(), EncodableValue(1.0)},
260 {EncodableValue("key"), EncodableValue("value")}}),
261 };
262
263 for (size_t i = 0; i < values.size(); ++i) {
264 const auto& a = values[i];
265 for (size_t j = 0; j < values.size(); ++j) {
266 const auto& b = values[j];
267 if (i == j) {
268 // Identical objects should always be equal.
269 EXPECT_FALSE(a < b);
270 EXPECT_FALSE(b < a);
271 } else {
272 // All other comparisons should be consistent, but the direction doesn't
273 // matter.
274 EXPECT_NE(a < b, b < a);
275 }
276 }
277
278 // Different non-collection objects with the same value should be equal;
279 // different collections should always be unequal regardless of contents.
280 bool is_collection = a.IsByteList() || a.IsIntList() || a.IsLongList() ||
281 a.IsDoubleList() || a.IsList() || a.IsMap();
282 EncodableValue copy(a);
283 bool is_equal = !(a < copy || copy < a);
284 EXPECT_EQ(is_equal, !is_collection);
285 }
286 }
287
288 // Tests that structures are deep-copied.
TEST(EncodableValueTest,DeepCopy)289 TEST(EncodableValueTest, DeepCopy) {
290 EncodableList encodables = {
291 EncodableValue(EncodableMap{
292 {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
293 {EncodableValue(1), EncodableValue(INT64_C(0000))},
294 {EncodableValue("two"), EncodableValue(7)},
295 }),
296 EncodableValue(EncodableList{
297 EncodableValue(),
298 EncodableValue(),
299 EncodableValue(
300 EncodableMap{{EncodableValue("a"), EncodableValue("b")}}),
301 }),
302 };
303
304 EncodableValue value(encodables);
305 ASSERT_TRUE(value.IsList());
306
307 // Spot-check innermost collection values.
308 EXPECT_EQ(value.ListValue()[0].MapValue()[EncodableValue("two")].IntValue(),
309 7);
310 EXPECT_EQ(value.ListValue()[1]
311 .ListValue()[2]
312 .MapValue()[EncodableValue("a")]
313 .StringValue(),
314 "b");
315
316 // Modify those values in the original structure.
317 encodables[0].MapValue()[EncodableValue("two")] = EncodableValue();
318 encodables[1].ListValue()[2].MapValue()[EncodableValue("a")] = 99;
319
320 // Re-check innermost collection values to ensure that they haven't changed.
321 EXPECT_EQ(value.ListValue()[0].MapValue()[EncodableValue("two")].IntValue(),
322 7);
323 EXPECT_EQ(value.ListValue()[1]
324 .ListValue()[2]
325 .MapValue()[EncodableValue("a")]
326 .StringValue(),
327 "b");
328 }
329
330 } // namespace flutter
331