| Flutter iOS Embedder |

standard_message_codec_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/standard_message_codec.h"
6
7 #include <map>
8 #include <vector>
9
10 #include "flutter/shell/platform/common/client_wrapper/testing/test_codec_extensions.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13
14 namespace flutter {
15
16 namespace {
17
18 class MockStandardCodecSerializer : public StandardCodecSerializer {
19 public:
20 MOCK_METHOD(void,
21 WriteValue,
22 (const EncodableValue& value, ByteStreamWriter* stream),
23 (const, override));
24 MOCK_METHOD(EncodableValue,
25 ReadValueOfType,
26 (uint8_t type, ByteStreamReader* stream),
27 (const, override));
28 };
29 } // namespace
30
31 // Validates round-trip encoding and decoding of |value|, and checks that the
32 // encoded value matches |expected_encoding|.
33 //
34 // If testing with CustomEncodableValues, |serializer| must be provided to
35 // handle the encoding/decoding, and |custom_comparator| must be provided to
36 // validate equality since CustomEncodableValue doesn't define a useful ==.
37 static void CheckEncodeDecode(
38 const EncodableValue& value,
39 const std::vector<uint8_t>& expected_encoding,
40 const StandardCodecSerializer* serializer = nullptr,
41 const std::function<bool(const EncodableValue& a, const EncodableValue& b)>&
42 custom_comparator = nullptr) {
43 const StandardMessageCodec& codec =
44 StandardMessageCodec::GetInstance(serializer);
45 auto encoded = codec.EncodeMessage(value);
46 ASSERT_TRUE(encoded);
47 EXPECT_EQ(*encoded, expected_encoding);
48
49 auto decoded = codec.DecodeMessage(*encoded);
50 if (custom_comparator) {
51 EXPECT_TRUE(custom_comparator(value, *decoded));
52 } else {
53 EXPECT_EQ(value, *decoded);
54 }
55 }
56
57 // Validates round-trip encoding and decoding of |value|, and checks that the
58 // encoded value has the given prefix and length.
59 //
60 // This should be used only for Map, where asserting the order of the elements
61 // in a test is undesirable.
62 static void CheckEncodeDecodeWithEncodePrefix(
63 const EncodableValue& value,
64 const std::vector<uint8_t>& expected_encoding_prefix,
65 size_t expected_encoding_length) {
66 EXPECT_TRUE(std::holds_alternative<EncodableMap>(value));
67 const StandardMessageCodec& codec = StandardMessageCodec::GetInstance();
68 auto encoded = codec.EncodeMessage(value);
69 ASSERT_TRUE(encoded);
70
71 EXPECT_EQ(encoded->size(), expected_encoding_length);
72 ASSERT_GT(encoded->size(), expected_encoding_prefix.size());
73 EXPECT_TRUE(std::equal(
74 encoded->begin(), encoded->begin() + expected_encoding_prefix.size(),
75 expected_encoding_prefix.begin(), expected_encoding_prefix.end()));
76
77 auto decoded = codec.DecodeMessage(*encoded);
78
79 EXPECT_EQ(value, *decoded);
80 }
81
82 TEST(StandardMessageCodec, GetInstanceCachesInstance) {
83 const StandardMessageCodec& codec_a =
84 StandardMessageCodec::GetInstance(nullptr);
85 const StandardMessageCodec& codec_b =
86 StandardMessageCodec::GetInstance(nullptr);
87 EXPECT_EQ(&codec_a, &codec_b);
88 }
89
90 TEST(StandardMessageCodec, CanEncodeAndDecodeNull) {
91 std::vector<uint8_t> bytes = {0x00};
92 CheckEncodeDecode(EncodableValue(), bytes);
93 }
94
95 TEST(StandardMessageCodec, CanDecodeEmptyBytesAsNullWithoutCallingSerializer) {
96 std::vector<uint8_t> bytes = {};
97 const MockStandardCodecSerializer serializer;
98 const StandardMessageCodec& codec =
99 StandardMessageCodec::GetInstance(&serializer);
100
101 auto decoded = codec.DecodeMessage(bytes);
102
103 EXPECT_EQ(EncodableValue(), *decoded);
104 EXPECT_CALL(serializer, ReadValueOfType(::testing::_, ::testing::_)).Times(0);
105 }
106
107 TEST(StandardMessageCodec, CanEncodeAndDecodeTrue) {
108 std::vector<uint8_t> bytes = {0x01};
109 CheckEncodeDecode(EncodableValue(true), bytes);
110 }
111
112 TEST(StandardMessageCodec, CanEncodeAndDecodeFalse) {
113 std::vector<uint8_t> bytes = {0x02};
114 CheckEncodeDecode(EncodableValue(false), bytes);
115 }
116
117 TEST(StandardMessageCodec, CanEncodeAndDecodeInt32) {
118 std::vector<uint8_t> bytes = {0x03, 0x78, 0x56, 0x34, 0x12};
119 CheckEncodeDecode(EncodableValue(0x12345678), bytes);
120 }
121
122 TEST(StandardMessageCodec, CanEncodeAndDecodeInt64) {
123 std::vector<uint8_t> bytes = {0x04, 0xef, 0xcd, 0xab, 0x90,
124 0x78, 0x56, 0x34, 0x12};
125 CheckEncodeDecode(EncodableValue(INT64_C(0x1234567890abcdef)), bytes);
126 }
127
128 TEST(StandardMessageCodec, CanEncodeAndDecodeDouble) {
129 std::vector<uint8_t> bytes = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
131 CheckEncodeDecode(EncodableValue(3.14159265358979311599796346854), bytes);
132 }
133
134 TEST(StandardMessageCodec, CanEncodeAndDecodeString) {
135 std::vector<uint8_t> bytes = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
136 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
137 CheckEncodeDecode(EncodableValue(u8"hello world"), bytes);
138 }
139
140 TEST(StandardMessageCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
141 std::vector<uint8_t> bytes = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
142 CheckEncodeDecode(EncodableValue(u8"h\u263Aw"), bytes);
143 }
144
145 TEST(StandardMessageCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
146 std::vector<uint8_t> bytes = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
147 CheckEncodeDecode(EncodableValue(u8"h\U0001F602w"), bytes);
148 }
149
150 TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyString) {
151 std::vector<uint8_t> bytes = {0x07, 0x00};
152 CheckEncodeDecode(EncodableValue(u8""), bytes);
153 }
154
155 TEST(StandardMessageCodec, CanEncodeAndDecodeList) {
156 std::vector<uint8_t> bytes = {
157 0x0c, 0x05, 0x00, 0x07, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x06,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e,
159 0x09, 0x40, 0x03, 0x2f, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x03, 0x2a,
160 0x00, 0x00, 0x00, 0x07, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64,
161 };
162 EncodableValue value(EncodableList{
163 EncodableValue(),
164 EncodableValue("hello"),
165 EncodableValue(3.14),
166 EncodableValue(47),
167 EncodableValue(EncodableList{
168 EncodableValue(42),
169 EncodableValue("nested"),
170 }),
171 });
172 CheckEncodeDecode(value, bytes);
173 }
174
175 TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyList) {
176 std::vector<uint8_t> bytes = {0x0c, 0x00};
177 CheckEncodeDecode(EncodableValue(EncodableList{}), bytes);
178 }
179
180 TEST(StandardMessageCodec, CanEncodeAndDecodeMap) {
181 std::vector<uint8_t> bytes_prefix = {0x0d, 0x04};
182 EncodableValue value(EncodableMap{
183 {EncodableValue("a"), EncodableValue(3.14)},
184 {EncodableValue("b"), EncodableValue(47)},
185 {EncodableValue(), EncodableValue()},
186 {EncodableValue(3.14), EncodableValue(EncodableList{
187 EncodableValue("nested"),
188 })},
189 });
190 CheckEncodeDecodeWithEncodePrefix(value, bytes_prefix, 48);
191 }
192
193 TEST(StandardMessageCodec, CanEncodeAndDecodeByteArray) {
194 std::vector<uint8_t> bytes = {0x08, 0x04, 0xba, 0x5e, 0xba, 0x11};
195 EncodableValue value(std::vector<uint8_t>{0xba, 0x5e, 0xba, 0x11});
196 CheckEncodeDecode(value, bytes);
197 }
198
199 TEST(StandardMessageCodec, CanEncodeAndDecodeInt32Array) {
200 std::vector<uint8_t> bytes = {0x09, 0x03, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12,
201 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
202 EncodableValue value(std::vector<int32_t>{0x12345678, -1, 0});
203 CheckEncodeDecode(value, bytes);
204 }
205
206 TEST(StandardMessageCodec, CanEncodeAndDecodeInt64Array) {
207 std::vector<uint8_t> bytes = {0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12,
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
210 EncodableValue value(std::vector<int64_t>{0x1234567890abcdef, -1});
211 CheckEncodeDecode(value, bytes);
212 }
213
214 TEST(StandardMessageCodec, CanEncodeAndDecodeFloat32Array) {
215 std::vector<uint8_t> bytes = {0x0e, 0x02, 0x00, 0x00, 0xd8, 0x0f,
216 0x49, 0x40, 0x00, 0x00, 0x7a, 0x44};
217 EncodableValue value(std::vector<float>{3.1415920257568359375f, 1000.0f});
218 CheckEncodeDecode(value, bytes);
219 }
220
221 TEST(StandardMessageCodec, CanEncodeAndDecodeFloat64Array) {
222 std::vector<uint8_t> bytes = {0x0b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8f, 0x40};
225 EncodableValue value(
226 std::vector<double>{3.14159265358979311599796346854, 1000.0});
227 CheckEncodeDecode(value, bytes);
228 }
229
230 TEST(StandardMessageCodec, CanEncodeAndDecodeSimpleCustomType) {
231 std::vector<uint8_t> bytes = {0x80, 0x09, 0x00, 0x00, 0x00,
232 0x10, 0x00, 0x00, 0x00};
233 auto point_comparator = [](const EncodableValue& a, const EncodableValue& b) {
234 const Point& a_point =
235 std::any_cast<Point>(std::get<CustomEncodableValue>(a));
236 const Point& b_point =
237 std::any_cast<Point>(std::get<CustomEncodableValue>(b));
238 return a_point == b_point;
239 };
240 CheckEncodeDecode(CustomEncodableValue(Point(9, 16)), bytes,
241 &PointExtensionSerializer::GetInstance(), point_comparator);
242 }
243
244 TEST(StandardMessageCodec, CanEncodeAndDecodeVariableLengthCustomType) {
245 std::vector<uint8_t> bytes = {
246 0x81, // custom type
247 0x06, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, // data
248 0x07, 0x04, // string type and length
249 0x74, 0x65, 0x73, 0x74 // string characters
250 };
251 auto some_data_comparator = [](const EncodableValue& a,
252 const EncodableValue& b) {
253 const SomeData& data_a =
254 std::any_cast<SomeData>(std::get<CustomEncodableValue>(a));
255 const SomeData& data_b =
256 std::any_cast<SomeData>(std::get<CustomEncodableValue>(b));
257 return data_a.data() == data_b.data() && data_a.label() == data_b.label();
258 };
259 CheckEncodeDecode(CustomEncodableValue(
260 SomeData("test", {0x00, 0x01, 0x02, 0x03, 0x04, 0x05})),
261 bytes, &SomeDataExtensionSerializer::GetInstance(),
262 some_data_comparator);
263 }
264
265 } // namespace flutter
flutter::CustomEncodableValue
Definition: encodable_value.h:60
flutter::EncodableValue
Definition: encodable_value.h:165
flutter::MessageCodec::EncodeMessage
std::unique_ptr< std::vector< uint8_t > > EncodeMessage(const T &message) const
Definition: message_codec.h:45
flutter::MessageCodec::DecodeMessage
std::unique_ptr< T > DecodeMessage(const uint8_t *binary_message, const size_t message_size) const
Definition: message_codec.h:29
flutter::Point
Definition: geometry.h:15
flutter::StandardCodecSerializer
Definition: standard_codec_serializer.h:18
flutter::StandardMessageCodec
Definition: standard_message_codec.h:18
flutter::StandardMessageCodec::GetInstance
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:293
flutter
Definition: accessibility_bridge.h:26
flutter::CheckEncodeDecodeWithEncodePrefix
static void CheckEncodeDecodeWithEncodePrefix(const EncodableValue &value, const std::vector< uint8_t > &expected_encoding_prefix, size_t expected_encoding_length)
Definition: standard_message_codec_unittests.cc:62
flutter::CheckEncodeDecode
static void CheckEncodeDecode(const EncodableValue &value, const std::vector< uint8_t > &expected_encoding, const StandardCodecSerializer *serializer=nullptr, const std::function< bool(const EncodableValue &a, const EncodableValue &b)> &custom_comparator=nullptr)
Definition: standard_message_codec_unittests.cc:37
flutter::EncodableList
std::vector< EncodableValue > EncodableList
Definition: encodable_value.h:94
flutter::EncodableMap
std::map< EncodableValue, EncodableValue > EncodableMap
Definition: encodable_value.h:95
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58
standard_message_codec.h