Flutter Engine
The Flutter Engine
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
14namespace flutter {
15
16namespace {
17
18class 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 ==.
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 =
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.
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));
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());
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
82TEST(StandardMessageCodec, GetInstanceCachesInstance) {
83 const StandardMessageCodec& codec_a =
85 const StandardMessageCodec& codec_b =
87 EXPECT_EQ(&codec_a, &codec_b);
88}
89
90TEST(StandardMessageCodec, CanEncodeAndDecodeNull) {
91 std::vector<uint8_t> bytes = {0x00};
93}
94
95TEST(StandardMessageCodec, CanDecodeEmptyBytesAsNullWithoutCallingSerializer) {
96 std::vector<uint8_t> bytes = {};
97 const MockStandardCodecSerializer serializer;
98 const StandardMessageCodec& codec =
100
101 auto decoded = codec.DecodeMessage(bytes);
102
103 EXPECT_EQ(EncodableValue(), *decoded);
104 EXPECT_CALL(serializer, ReadValueOfType(::testing::_, ::testing::_)).Times(0);
105}
106
107TEST(StandardMessageCodec, CanEncodeAndDecodeTrue) {
108 std::vector<uint8_t> bytes = {0x01};
109 CheckEncodeDecode(EncodableValue(true), bytes);
110}
111
112TEST(StandardMessageCodec, CanEncodeAndDecodeFalse) {
113 std::vector<uint8_t> bytes = {0x02};
114 CheckEncodeDecode(EncodableValue(false), bytes);
115}
116
117TEST(StandardMessageCodec, CanEncodeAndDecodeInt32) {
118 std::vector<uint8_t> bytes = {0x03, 0x78, 0x56, 0x34, 0x12};
119 CheckEncodeDecode(EncodableValue(0x12345678), bytes);
120}
121
122TEST(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
128TEST(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
134TEST(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
140TEST(StandardMessageCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
141 std::vector<uint8_t> bytes = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
142 CheckEncodeDecode(EncodableValue(u8"h\u263Aw"), bytes);
143}
144
145TEST(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
150TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyString) {
151 std::vector<uint8_t> bytes = {0x07, 0x00};
152 CheckEncodeDecode(EncodableValue(u8""), bytes);
153}
154
155TEST(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 };
164 EncodableValue("hello"),
165 EncodableValue(3.14),
166 EncodableValue(47),
168 EncodableValue(42),
169 EncodableValue("nested"),
170 }),
171 });
172 CheckEncodeDecode(value, bytes);
173}
174
175TEST(StandardMessageCodec, CanEncodeAndDecodeEmptyList) {
176 std::vector<uint8_t> bytes = {0x0c, 0x00};
178}
179
180TEST(StandardMessageCodec, CanEncodeAndDecodeMap) {
181 std::vector<uint8_t> bytes_prefix = {0x0d, 0x04};
183 {EncodableValue("a"), EncodableValue(3.14)},
184 {EncodableValue("b"), EncodableValue(47)},
187 EncodableValue("nested"),
188 })},
189 });
190 CheckEncodeDecodeWithEncodePrefix(value, bytes_prefix, 48);
191}
192
193TEST(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
199TEST(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
206TEST(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
214TEST(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
221TEST(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};
226 std::vector<double>{3.14159265358979311599796346854, 1000.0});
227 CheckEncodeDecode(value, bytes);
228}
229
230TEST(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 };
241 &PointExtensionSerializer::GetInstance(), point_comparator);
242}
243
244TEST(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 };
260 SomeData("test", {0x00, 0x01, 0x02, 0x03, 0x04, 0x05})),
262 some_data_comparator);
263}
264
265} // namespace flutter
static bool equal(const SkBitmap &a, const SkBitmap &b)
Definition: ImageTest.cpp:1395
GLenum type
std::unique_ptr< T > DecodeMessage(const uint8_t *binary_message, const size_t message_size) const
Definition: message_codec.h:29
std::unique_ptr< std::vector< uint8_t > > EncodeMessage(const T &message) const
Definition: message_codec.h:45
static const PointExtensionSerializer & GetInstance()
static const SomeDataExtensionSerializer & GetInstance()
const std::string & label() const
const std::vector< uint8_t > & data() const
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
static bool b
struct MyStruct a[10]
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
TEST(FrameTimingsRecorderTest, RecordVsync)
static void CheckEncodeDecodeWithEncodePrefix(const EncodableValue &value, const std::vector< uint8_t > &expected_encoding_prefix, size_t expected_encoding_length)
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)
std::vector< EncodableValue > EncodableList
std::map< EncodableValue, EncodableValue > EncodableMap
TPoint< Scalar > Point
Definition: point.h:322
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678