Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
11namespace flutter {
12
13TEST(EncodableValueTest, Null) {
15 value.IsNull();
16}
17
18TEST(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
26TEST(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.
35TEST(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
42TEST(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
50TEST(EncodableValueTest, Double) {
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
58TEST(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.
68TEST(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
77TEST(EncodableValueTest, UInt8List) {
78 std::vector<uint8_t> data = {0, 2};
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
91TEST(EncodableValueTest, Int32List) {
92 std::vector<int32_t> data = {-10, 2};
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
105TEST(EncodableValueTest, Int64List) {
106 std::vector<int64_t> data = {-10, 2};
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
119TEST(EncodableValueTest, DoubleList) {
120 std::vector<double> data = {-10.0, 2.0};
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
133TEST(EncodableValueTest, List) {
134 EncodableList encodables = {
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
153TEST(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.
177TEST(EncodableValueTest, Comparison) {
178 EncodableList values = {
179 // Null
181 // Bool
182 EncodableValue(true),
183 EncodableValue(false),
184 // Int
185 EncodableValue(-7),
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.
242 EXPECT_FALSE(a < copy || copy < a);
243 }
244}
245
246// Tests that structures are deep-copied.
247TEST(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 }),
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
301TEST(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
#define TEST(S, s, D, expected)
static bool b
struct MyStruct a[10]
uint8_t value
Definition copy.py:1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
std::vector< EncodableValue > EncodableList
std::map< EncodableValue, EncodableValue > EncodableMap
#define EXPECT_TRUE(handle)
Definition unit_test.h:685