• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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