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