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/cpp/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  EncodableValue value(std::numeric_limits<int32_t>::max());
37  EXPECT_EQ(value.LongValue(), std::numeric_limits<int32_t>::max());
38  value = std::numeric_limits<int64_t>::max();
39  EXPECT_EQ(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  };
221 
222  for (size_t i = 0; i < values.size(); ++i) {
223  const auto& a = values[i];
224  for (size_t j = 0; j < values.size(); ++j) {
225  const auto& b = values[j];
226  if (i == j) {
227  // Identical objects should always be equal.
228  EXPECT_FALSE(a < b);
229  EXPECT_FALSE(b < a);
230  } else {
231  // All other comparisons should be consistent, but the direction doesn't
232  // matter.
233  EXPECT_NE(a < b, b < a) << "Indexes: " << i << ", " << j;
234  }
235  }
236 
237  // Copies should always be equal.
238  EncodableValue copy(a);
239  EXPECT_FALSE(a < copy || copy < a);
240  }
241 }
242 
243 // Tests that structures are deep-copied.
244 TEST(EncodableValueTest, DeepCopy) {
245  EncodableList original = {
247  {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
248  {EncodableValue(1), EncodableValue(INT64_C(0000))},
249  {EncodableValue("two"), EncodableValue(7)},
250  }),
252  EncodableValue(),
253  EncodableValue(),
256  }),
257  };
258 
259  EncodableValue copy(original);
260  ASSERT_TRUE(std::holds_alternative<EncodableList>(copy));
261 
262  // Spot-check innermost collection values.
263  auto& root_list = std::get<EncodableList>(copy);
264  auto& first_child = std::get<EncodableMap>(root_list[0]);
265  EXPECT_EQ(std::get<int32_t>(first_child[EncodableValue("two")]), 7);
266  auto& second_child = std::get<EncodableList>(root_list[1]);
267  auto& innermost_map = std::get<EncodableMap>(second_child[2]);
268  EXPECT_EQ(std::get<std::string>(innermost_map[EncodableValue("a")]), "b");
269 
270  // Modify those values in the original structure.
271  first_child[EncodableValue("two")] = EncodableValue();
272  innermost_map[EncodableValue("a")] = 99;
273 
274  // Re-check innermost collection values of the original to ensure that they
275  // haven't changed.
276  first_child = std::get<EncodableMap>(original[0]);
277  EXPECT_EQ(std::get<int32_t>(first_child[EncodableValue("two")]), 7);
278  second_child = std::get<EncodableList>(original[1]);
279  innermost_map = std::get<EncodableMap>(second_child[2]);
280  EXPECT_EQ(std::get<std::string>(innermost_map[EncodableValue("a")]), "b");
281 }
282 
283 } // namespace flutter
uint8_t value
std::vector< EncodableValue > EncodableList
TEST(DartServiceIsolateTest, CanAddAndRemoveHandles)
std::map< EncodableValue, EncodableValue > EncodableMap