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