| Flutter iOS Embedder |

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) {
14 EncodableValue value;
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) {
27 EncodableValue value(42);
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
212 EncodableValue(EncodableList{EncodableValue(), EncodableValue(true)}),
213 EncodableValue(EncodableList{EncodableValue(), EncodableValue(1.0)}),
214 // Map
215 EncodableValue(EncodableMap{{EncodableValue(), EncodableValue(true)},
216 {EncodableValue(7), EncodableValue(7.0)}}),
217 EncodableValue(
218 EncodableMap{{EncodableValue(), EncodableValue(1.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 = {
249 EncodableValue(EncodableMap{
250 {EncodableValue(), EncodableValue(std::vector<int32_t>{1, 2, 3})},
251 {EncodableValue(1), EncodableValue(INT64_C(0000))},
252 {EncodableValue("two"), EncodableValue(7)},
253 }),
254 EncodableValue(EncodableList{
255 EncodableValue(),
256 EncodableValue(),
257 EncodableValue(
258 EncodableMap{{EncodableValue("a"), EncodableValue("b")}}),
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
287 class TestCustomValue {
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
flutter::CustomEncodableValue
Definition: encodable_value.h:61
flutter::EncodableValue
Definition: encodable_value.h:166
flutter::EncodableValue::IsNull
bool IsNull() const
Definition: encodable_value.h:204
flutter::EncodableValue::LongValue
int64_t LongValue() const
Definition: encodable_value.h:213
flutter::TestCustomValue
Definition: encodable_value_unittests.cc:287
flutter::TestCustomValue::y
int y() const
Definition: encodable_value_unittests.cc:294
flutter::TestCustomValue::TestCustomValue
TestCustomValue()
Definition: encodable_value_unittests.cc:289
flutter::TestCustomValue::x
int x() const
Definition: encodable_value_unittests.cc:293
flutter::TestCustomValue::TestCustomValue
TestCustomValue(int x, int y)
Definition: encodable_value_unittests.cc:290
flutter::TestCustomValue::~TestCustomValue
~TestCustomValue()=default
encodable_value.h
flutter
Definition: accessibility_bridge.h:26
flutter::EncodableList
std::vector< EncodableValue > EncodableList
Definition: encodable_value.h:95
flutter::EncodableMap
std::map< EncodableValue, EncodableValue > EncodableMap
Definition: encodable_value.h:96
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58