Flutter Engine
encodable_value_unittests.cc
Go to the documentation of this file.
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/client_wrapper/include/flutter/encodable_value.h"
6 
7 #include <limits>
8 
9 #include "gtest/gtest.h"
10 
11 namespace flutter {
12 
13 TEST(EncodableValueTest, Null) {
15  value.IsNull();
16 }
17 
18 TEST(EncodableValueTest, Bool) {
19  EncodableValue value(false);
20 
21  EXPECT_FALSE(std::get<bool>(value));
22  value = true;
23  EXPECT_TRUE(std::get<bool>(value));
24 }
25 
26 TEST(EncodableValueTest, Int) {
28 
29  EXPECT_EQ(std::get<int32_t>(value), 42);
30  value = std::numeric_limits<int32_t>::max();
31  EXPECT_EQ(std::get<int32_t>(value), std::numeric_limits<int32_t>::max());
32 }
33 
34 // Test the int/long convenience wrapper.
35 TEST(EncodableValueTest, LongValue) {
36  const EncodableValue int_value(std::numeric_limits<int32_t>::max());
37  EXPECT_EQ(int_value.LongValue(), std::numeric_limits<int32_t>::max());
38  const EncodableValue long_value(std::numeric_limits<int64_t>::max());
39  EXPECT_EQ(long_value.LongValue(), std::numeric_limits<int64_t>::max());
40 }
41 
42 TEST(EncodableValueTest, Long) {
43  EncodableValue value(INT64_C(42));
44 
45  EXPECT_EQ(std::get<int64_t>(value), 42);
46  value = std::numeric_limits<int64_t>::max();
47  EXPECT_EQ(std::get<int64_t>(value), std::numeric_limits<int64_t>::max());
48 }
49 
50 TEST(EncodableValueTest, Double) {
51  EncodableValue value(3.14);
52 
53  EXPECT_EQ(std::get<double>(value), 3.14);
54  value = std::numeric_limits<double>::max();
55  EXPECT_EQ(std::get<double>(value), std::numeric_limits<double>::max());
56 }
57 
58 TEST(EncodableValueTest, String) {
59  std::string hello("Hello, world!");
60  EncodableValue value(hello);
61 
62  EXPECT_EQ(std::get<std::string>(value), hello);
63  value = std::string("Goodbye");
64  EXPECT_EQ(std::get<std::string>(value), "Goodbye");
65 }
66 
67 // Explicitly verify that the overrides to prevent char*->bool conversions work.
68 TEST(EncodableValueTest, CString) {
69  const char* hello = "Hello, world!";
70  EncodableValue value(hello);
71 
72  EXPECT_EQ(std::get<std::string>(value), hello);
73  value = "Goodbye";
74  EXPECT_EQ(std::get<std::string>(value), "Goodbye");
75 }
76 
77 TEST(EncodableValueTest, UInt8List) {
78  std::vector<uint8_t> data = {0, 2};
79  EncodableValue value(data);
80 
81  auto& list_value = std::get<std::vector<uint8_t>>(value);
82  list_value.push_back(std::numeric_limits<uint8_t>::max());
83  EXPECT_EQ(list_value[0], 0);
84  EXPECT_EQ(list_value[1], 2);
85 
86  ASSERT_EQ(list_value.size(), 3u);
87  EXPECT_EQ(data.size(), 2u);
88  EXPECT_EQ(list_value[2], std::numeric_limits<uint8_t>::max());
89 }
90 
91 TEST(EncodableValueTest, Int32List) {
92  std::vector<int32_t> data = {-10, 2};
93  EncodableValue value(data);
94 
95  auto& list_value = std::get<std::vector<int32_t>>(value);
96  list_value.push_back(std::numeric_limits<int32_t>::max());
97  EXPECT_EQ(list_value[0], -10);
98  EXPECT_EQ(list_value[1], 2);
99 
100  ASSERT_EQ(list_value.size(), 3u);
101  EXPECT_EQ(data.size(), 2u);
102  EXPECT_EQ(list_value[2], std::numeric_limits<int32_t>::max());
103 }
104 
105 TEST(EncodableValueTest, Int64List) {
106  std::vector<int64_t> data = {-10, 2};
107  EncodableValue value(data);
108 
109  auto& list_value = std::get<std::vector<int64_t>>(value);
110  list_value.push_back(std::numeric_limits<int64_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<int64_t>::max());
117 }
118 
119 TEST(EncodableValueTest, DoubleList) {
120  std::vector<double> data = {-10.0, 2.0};
121  EncodableValue value(data);
122 
123  auto& list_value = std::get<std::vector<double>>(value);
124  list_value.push_back(std::numeric_limits<double>::max());
125  EXPECT_EQ(list_value[0], -10.0);
126  EXPECT_EQ(list_value[1], 2.0);
127 
128  ASSERT_EQ(list_value.size(), 3u);
129  EXPECT_EQ(data.size(), 2u);
130  EXPECT_EQ(list_value[2], std::numeric_limits<double>::max());
131 }
132 
133 TEST(EncodableValueTest, List) {
134  EncodableList encodables = {
135  EncodableValue(1),
136  EncodableValue(2.0),
137  EncodableValue("Three"),
138  };
139  EncodableValue value(encodables);
140 
141  auto& list_value = std::get<EncodableList>(value);
142  EXPECT_EQ(std::get<int32_t>(list_value[0]), 1);
143  EXPECT_EQ(std::get<double>(list_value[1]), 2.0);
144  EXPECT_EQ(std::get<std::string>(list_value[2]), "Three");
145 
146  // Ensure that it's a modifiable copy of the original array.
147  list_value.push_back(EncodableValue(true));
148  ASSERT_EQ(list_value.size(), 4u);
149  EXPECT_EQ(encodables.size(), 3u);
150  EXPECT_EQ(std::get<bool>(std::get<EncodableList>(value)[3]), true);
151 }
152 
153 TEST(EncodableValueTest, Map) {
154  EncodableMap encodables = {
155  {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
156  {EncodableValue(1), EncodableValue(INT64_C(10000))},
157  {EncodableValue("two"), EncodableValue(7)},
158  };
159  EncodableValue value(encodables);
160 
161  auto& map_value = std::get<EncodableMap>(value);
162  EXPECT_EQ(
163  std::holds_alternative<std::vector<int32_t>>(map_value[EncodableValue()]),
164  true);
165  EXPECT_EQ(std::get<int64_t>(map_value[EncodableValue(1)]), INT64_C(10000));
166  EXPECT_EQ(std::get<int32_t>(map_value[EncodableValue("two")]), 7);
167 
168  // Ensure that it's a modifiable copy of the original map.
169  map_value[EncodableValue(true)] = EncodableValue(false);
170  ASSERT_EQ(map_value.size(), 4u);
171  EXPECT_EQ(encodables.size(), 3u);
172  EXPECT_EQ(std::get<bool>(map_value[EncodableValue(true)]), false);
173 }
174 
175 // Tests that the < operator meets the requirements of using EncodableValue as
176 // a map key.
177 TEST(EncodableValueTest, Comparison) {
178  EncodableList values = {
179  // Null
180  EncodableValue(),
181  // Bool
182  EncodableValue(true),
183  EncodableValue(false),
184  // Int
185  EncodableValue(-7),
186  EncodableValue(0),
187  EncodableValue(100),
188  // Long
189  EncodableValue(INT64_C(-7)),
190  EncodableValue(INT64_C(0)),
191  EncodableValue(INT64_C(100)),
192  // Double
193  EncodableValue(-7.0),
194  EncodableValue(0.0),
195  EncodableValue(100.0),
196  // String
197  EncodableValue("one"),
198  EncodableValue("two"),
199  // ByteList
200  EncodableValue(std::vector<uint8_t>{0, 1}),
201  EncodableValue(std::vector<uint8_t>{0, 10}),
202  // IntList
203  EncodableValue(std::vector<int32_t>{0, 1}),
204  EncodableValue(std::vector<int32_t>{0, 100}),
205  // LongList
206  EncodableValue(std::vector<int64_t>{0, INT64_C(1)}),
207  EncodableValue(std::vector<int64_t>{0, INT64_C(100)}),
208  // DoubleList
209  EncodableValue(std::vector<double>{0, INT64_C(1)}),
210  EncodableValue(std::vector<double>{0, INT64_C(100)}),
211  // List
214  // Map
216  {EncodableValue(7), EncodableValue(7.0)}}),
219  {EncodableValue("key"), EncodableValue("value")}}),
220  // FloatList
221  EncodableValue(std::vector<float>{0, 1}),
222  EncodableValue(std::vector<float>{0, 100}),
223  };
224 
225  for (size_t i = 0; i < values.size(); ++i) {
226  const auto& a = values[i];
227  for (size_t j = 0; j < values.size(); ++j) {
228  const auto& b = values[j];
229  if (i == j) {
230  // Identical objects should always be equal.
231  EXPECT_FALSE(a < b);
232  EXPECT_FALSE(b < a);
233  } else {
234  // All other comparisons should be consistent, but the direction doesn't
235  // matter.
236  EXPECT_NE(a < b, b < a) << "Indexes: " << i << ", " << j;
237  }
238  }
239 
240  // Copies should always be equal.
241  EncodableValue copy(a);
242  EXPECT_FALSE(a < copy || copy < a);
243  }
244 }
245 
246 // Tests that structures are deep-copied.
247 TEST(EncodableValueTest, DeepCopy) {
248  EncodableList original = {
250  {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
251  {EncodableValue(1), EncodableValue(INT64_C(0000))},
252  {EncodableValue("two"), EncodableValue(7)},
253  }),
255  EncodableValue(),
256  EncodableValue(),
259  }),
260  };
261 
262  EncodableValue copy(original);
263  ASSERT_TRUE(std::holds_alternative<EncodableList>(copy));
264 
265  // Spot-check innermost collection values.
266  auto& root_list = std::get<EncodableList>(copy);
267  auto& first_child = std::get<EncodableMap>(root_list[0]);
268  EXPECT_EQ(std::get<int32_t>(first_child[EncodableValue("two")]), 7);
269  auto& second_child = std::get<EncodableList>(root_list[1]);
270  auto& innermost_map = std::get<EncodableMap>(second_child[2]);
271  EXPECT_EQ(std::get<std::string>(innermost_map[EncodableValue("a")]), "b");
272 
273  // Modify those values in the original structure.
274  first_child[EncodableValue("two")] = EncodableValue();
275  innermost_map[EncodableValue("a")] = 99;
276 
277  // Re-check innermost collection values of the original to ensure that they
278  // haven't changed.
279  first_child = std::get<EncodableMap>(original[0]);
280  EXPECT_EQ(std::get<int32_t>(first_child[EncodableValue("two")]), 7);
281  second_child = std::get<EncodableList>(original[1]);
282  innermost_map = std::get<EncodableMap>(second_child[2]);
283  EXPECT_EQ(std::get<std::string>(innermost_map[EncodableValue("a")]), "b");
284 }
285 
286 // Simple class for testing custom encodable values
288  public:
289  TestCustomValue() : x_(0), y_(0) {}
290  TestCustomValue(int x, int y) : x_(x), y_(y) {}
291  ~TestCustomValue() = default;
292 
293  int x() const { return x_; }
294  int y() const { return y_; }
295 
296  private:
297  int x_;
298  int y_;
299 };
300 
301 TEST(EncodableValueTest, TypeIndexesCorrect) {
302  // Null
303  EXPECT_EQ(EncodableValue().index(), 0u);
304  // Bool
305  EXPECT_EQ(EncodableValue(true).index(), 1u);
306  // Int32
307  EXPECT_EQ(EncodableValue(100).index(), 2u);
308  // Int64
309  EXPECT_EQ(EncodableValue(INT64_C(100)).index(), 3u);
310  // Double
311  EXPECT_EQ(EncodableValue(7.0).index(), 4u);
312  // String
313  EXPECT_EQ(EncodableValue("one").index(), 5u);
314  // ByteList
315  EXPECT_EQ(EncodableValue(std::vector<uint8_t>()).index(), 6u);
316  // IntList
317  EXPECT_EQ(EncodableValue(std::vector<int32_t>()).index(), 7u);
318  // LongList
319  EXPECT_EQ(EncodableValue(std::vector<int64_t>()).index(), 8u);
320  // DoubleList
321  EXPECT_EQ(EncodableValue(std::vector<double>()).index(), 9u);
322  // List
323  EXPECT_EQ(EncodableValue(EncodableList()).index(), 10u);
324  // Map
325  EXPECT_EQ(EncodableValue(EncodableMap()).index(), 11u);
326  // Custom type
327  TestCustomValue customValue;
328  EXPECT_EQ(((EncodableValue)CustomEncodableValue(customValue)).index(), 12u);
329  // FloatList
330  EXPECT_EQ(EncodableValue(std::vector<float>()).index(), 13u);
331 } // namespace flutter
332 
333 } // namespace flutter
uint8_t value
int64_t LongValue() const
std::vector< EncodableValue > EncodableList
TEST(DartServiceIsolateTest, CanAddAndRemoveHandles)
std::map< EncodableValue, EncodableValue > EncodableMap