Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
11namespace flutter {
12
13namespace {
14
15// Returns true if the given method calls have the same method name, and their
16// arguments have equivalent values.
17bool 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
35TEST(StandardMethodCodec, GetInstanceCachesInstance) {
36 const StandardMethodCodec& codec_a =
38 const StandardMethodCodec& codec_b =
40 EXPECT_EQ(&codec_a, &codec_b);
41}
42
43TEST(StandardMethodCodec, HandlesMethodCallsWithNullArguments) {
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
53TEST(StandardMethodCodec, HandlesMethodCallsWithArgument) {
55 MethodCall<> call("hello", std::make_unique<EncodableValue>(EncodableList{
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
66TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithNullResult) {
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
85TEST(StandardMethodCodec, HandlesSuccessEnvelopesWithResult) {
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
105TEST(StandardMethodCodec, HandlesErrorEnvelopesWithNulls) {
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
130TEST(StandardMethodCodec, HandlesErrorEnvelopesWithDetails) {
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
167TEST(StandardMethodCodec, HandlesCustomTypeArguments) {
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
#define TEST(S, s, D, expected)
std::unique_ptr< MethodCall< T > > DecodeMethodCall(const uint8_t *message, size_t message_size) const
bool DecodeAndProcessResponseEnvelope(const uint8_t *response, size_t response_size, MethodResult< T > *result) const
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelope(const std::string &error_code, const std::string &error_message="", const T *error_details=nullptr) const
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCall(const MethodCall< T > &method_call) const
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelope(const T *result=nullptr) const
static const PointExtensionSerializer & GetInstance()
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
static bool b
struct MyStruct a[10]
GAsyncResult * result
Win32Message message
std::vector< EncodableValue > EncodableList
#define EXPECT_TRUE(handle)
Definition unit_test.h:685