| Flutter iOS Embedder |

standard_method_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_method_codec.h"
6
7 #include "flutter/shell/platform/common/client_wrapper/include/flutter/method_result_functions.h"
8 #include "flutter/shell/platform/common/client_wrapper/testing/test_codec_extensions.h"
9 #include "gtest/gtest.h"
10
11 namespace flutter {
12
13 namespace {
14
15 // Returns true if the given method calls have the same method name, and their
16 // arguments have equivalent values.
17 bool MethodCallsAreEqual(const MethodCall<>& a, const MethodCall<>& b) {
18 if (a.method_name() != b.method_name()) {
19 return false;
20 }
21 // Treat nullptr and Null as equivalent.
22 if ((!a.arguments() || a.arguments()->IsNull()) &&
23 (!b.arguments() || b.arguments()->IsNull())) {
24 return true;
25 }
26 // If only one is nullptr, fail early rather than throw below.
27 if (!a.arguments() || !b.arguments()) {
28 return false;
29 }
30 return *a.arguments() == *b.arguments();
31 }
32
33 } // namespace
34
35 TEST(StandardMethodCodec, GetInstanceCachesInstance) {
36 const StandardMethodCodec& codec_a =
37 StandardMethodCodec::GetInstance(nullptr);
38 const StandardMethodCodec& codec_b =
39 StandardMethodCodec::GetInstance(nullptr);
40 EXPECT_EQ(&codec_a, &codec_b);
41 }
42
43 TEST(StandardMethodCodec, HandlesMethodCallsWithNullArguments) {
44 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
45 MethodCall<> call("hello", nullptr);
46 auto encoded = codec.EncodeMethodCall(call);
47 ASSERT_NE(encoded.get(), nullptr);
48 std::unique_ptr<MethodCall<>> decoded = codec.DecodeMethodCall(*encoded);
49 ASSERT_NE(decoded.get(), nullptr);
50 EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
51 }
52
53 TEST(StandardMethodCodec, HandlesMethodCallsWithArgument) {
54 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
55 MethodCall<> call("hello", std::make_unique<EncodableValue>(EncodableList{
56 EncodableValue(42),
57 EncodableValue("world"),
58 }));
59 auto encoded = codec.EncodeMethodCall(call);
60 ASSERT_NE(encoded.get(), nullptr);
61 std::unique_ptr<MethodCall<>> decoded = codec.DecodeMethodCall(*encoded);
62 ASSERT_NE(decoded.get(), nullptr);
63 EXPECT_TRUE(MethodCallsAreEqual(call, *decoded));
64 }
65
66 TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithNullResult) {
67 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
68 auto encoded = codec.EncodeSuccessEnvelope();
69 ASSERT_NE(encoded.get(), nullptr);
70 std::vector<uint8_t> bytes = {0x00, 0x00};
71 EXPECT_EQ(*encoded, bytes);
72
73 bool decoded_successfully = false;
74 MethodResultFunctions<> result_handler(
75 [&decoded_successfully](const EncodableValue* result) {
76 decoded_successfully = true;
77 EXPECT_EQ(result, nullptr);
78 },
79 nullptr, nullptr);
80 codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
81 &result_handler);
82 EXPECT_TRUE(decoded_successfully);
83 }
84
85 TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithResult) {
86 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
87 EncodableValue result(42);
88 auto encoded = codec.EncodeSuccessEnvelope(&result);
89 ASSERT_NE(encoded.get(), nullptr);
90 std::vector<uint8_t> bytes = {0x00, 0x03, 0x2a, 0x00, 0x00, 0x00};
91 EXPECT_EQ(*encoded, bytes);
92
93 bool decoded_successfully = false;
94 MethodResultFunctions<> result_handler(
95 [&decoded_successfully](const EncodableValue* result) {
96 decoded_successfully = true;
97 EXPECT_EQ(std::get<int32_t>(*result), 42);
98 },
99 nullptr, nullptr);
100 codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
101 &result_handler);
102 EXPECT_TRUE(decoded_successfully);
103 }
104
105 TEST(StandardMethodCodec, HandlesErrorEnvelopesWithNulls) {
106 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
107 auto encoded = codec.EncodeErrorEnvelope("errorCode");
108 ASSERT_NE(encoded.get(), nullptr);
109 std::vector<uint8_t> bytes = {0x01, 0x07, 0x09, 0x65, 0x72, 0x72, 0x6f,
110 0x72, 0x43, 0x6f, 0x64, 0x65, 0x00, 0x00};
111 EXPECT_EQ(*encoded, bytes);
112
113 bool decoded_successfully = false;
114 MethodResultFunctions<> result_handler(
115 nullptr,
116 [&decoded_successfully](const std::string& code,
117 const std::string& message,
118 const EncodableValue* details) {
119 decoded_successfully = true;
120 EXPECT_EQ(code, "errorCode");
121 EXPECT_EQ(message, "");
122 EXPECT_EQ(details, nullptr);
123 },
124 nullptr);
125 codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
126 &result_handler);
127 EXPECT_TRUE(decoded_successfully);
128 }
129
130 TEST(StandardMethodCodec, HandlesErrorEnvelopesWithDetails) {
131 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance();
132 EncodableValue details(EncodableList{
133 EncodableValue("a"),
134 EncodableValue(42),
135 });
136 auto encoded =
137 codec.EncodeErrorEnvelope("errorCode", "something failed", &details);
138 ASSERT_NE(encoded.get(), nullptr);
139 std::vector<uint8_t> bytes = {
140 0x01, 0x07, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f,
141 0x64, 0x65, 0x07, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68,
142 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64,
143 0x0c, 0x02, 0x07, 0x01, 0x61, 0x03, 0x2a, 0x00, 0x00, 0x00,
144 };
145 EXPECT_EQ(*encoded, bytes);
146
147 bool decoded_successfully = false;
148 MethodResultFunctions<> result_handler(
149 nullptr,
150 [&decoded_successfully](const std::string& code,
151 const std::string& message,
152 const EncodableValue* details) {
153 decoded_successfully = true;
154 EXPECT_EQ(code, "errorCode");
155 EXPECT_EQ(message, "something failed");
156 const auto* details_list = std::get_if<EncodableList>(details);
157 ASSERT_NE(details_list, nullptr);
158 EXPECT_EQ(std::get<std::string>((*details_list)[0]), "a");
159 EXPECT_EQ(std::get<int32_t>((*details_list)[1]), 42);
160 },
161 nullptr);
162 codec.DecodeAndProcessResponseEnvelope(encoded->data(), encoded->size(),
163 &result_handler);
164 EXPECT_TRUE(decoded_successfully);
165 }
166
167 TEST(StandardMethodCodec, HandlesCustomTypeArguments) {
168 const StandardMethodCodec& codec = StandardMethodCodec::GetInstance(
169 &PointExtensionSerializer::GetInstance());
170 Point point(7, 9);
171 MethodCall<> call(
172 "hello", std::make_unique<EncodableValue>(CustomEncodableValue(point)));
173 auto encoded = codec.EncodeMethodCall(call);
174 ASSERT_NE(encoded.get(), nullptr);
175 std::unique_ptr<MethodCall<>> decoded = codec.DecodeMethodCall(*encoded);
176 ASSERT_NE(decoded.get(), nullptr);
177
178 const Point& decoded_point = std::any_cast<Point>(
179 std::get<CustomEncodableValue>(*decoded->arguments()));
180 EXPECT_EQ(point, decoded_point);
181 };
182
183 } // namespace flutter
flutter::TEST
TEST(BasicMessageChannelTest, Registration)
Definition: basic_message_channel_unittests.cc:58
method_result_functions.h
flutter::MethodCodec::EncodeErrorEnvelope
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelope(const std::string &error_code, const std::string &error_message="", const T *error_details=nullptr) const
Definition: method_codec.h:62
flutter::StandardMethodCodec
Definition: standard_method_codec.h:18
standard_method_codec.h
flutter::MethodCall
Definition: method_call.h:18
flutter::MethodCodec::EncodeSuccessEnvelope
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
Definition: method_codec.h:55
flutter::MethodCodec::EncodeMethodCall
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
Definition: method_codec.h:48
flutter
Definition: accessibility_bridge.h:28
flutter::EncodableValue
Definition: encodable_value.h:165
flutter::Point
Definition: geometry.h:13
flutter::EncodableList
std::vector< EncodableValue > EncodableList
Definition: encodable_value.h:94
flutter::MethodCodec::DecodeMethodCall
std::unique_ptr< MethodCall< T > > DecodeMethodCall(const uint8_t *message, size_t message_size) const
Definition: method_codec.h:32
flutter::StandardMethodCodec::GetInstance
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:340
flutter::MethodResultFunctions
Definition: method_result_functions.h:31
flutter::MethodCodec::DecodeAndProcessResponseEnvelope
bool DecodeAndProcessResponseEnvelope(const uint8_t *response, size_t response_size, MethodResult< T > *result) const
Definition: method_codec.h:75
flutter::CustomEncodableValue
Definition: encodable_value.h:60