Flutter Engine
The Flutter Engine
fl_method_codec_test.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/linux/public/flutter_linux/fl_method_codec.h"
6
7#include <cstring>
8
9#include "flutter/shell/platform/linux/fl_method_codec_private.h"
10#include "flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h"
11#include "gtest/gtest.h"
12
13G_DECLARE_FINAL_TYPE(FlTestMethodCodec,
14 fl_test_method_codec,
15 FL,
16 TEST_METHOD_CODEC,
17 FlMethodCodec)
18
19// Implement the FlMethodCodec API for the following tests to check it works as
20// expected.
21struct _FlTestMethodCodec {
22 FlMethodCodec parent_instance;
23};
24
25G_DEFINE_TYPE(FlTestMethodCodec,
26 fl_test_method_codec,
27 fl_method_codec_get_type())
28
29// Helper function to convert binary data to text.
30static gchar* message_to_text(GBytes* message) {
31 size_t data_length;
32 const gchar* data =
33 static_cast<const gchar*>(g_bytes_get_data(message, &data_length));
34 return g_strndup(data, data_length);
35}
36
37// Helper function to convert text to binary data.
38static GBytes* text_to_message(const gchar* text) {
39 return g_bytes_new(text, strlen(text));
40}
41
42// Implements FlMethodCodec::encode_method_call.
43static GBytes* fl_test_codec_encode_method_call(FlMethodCodec* codec,
44 const gchar* name,
46 GError** error) {
47 EXPECT_TRUE(FL_IS_TEST_METHOD_CODEC(codec));
48
49 g_autofree gchar* text = nullptr;
50 if (args == nullptr || fl_value_get_type(args) == FL_VALUE_TYPE_NULL) {
51 text = g_strdup_printf("%s()", name);
53 text = g_strdup_printf("%s(%" G_GINT64_FORMAT ")", name,
55 } else {
57 "ERROR");
58 return nullptr;
59 }
60
61 return text_to_message(text);
62}
63
64// Implements FlMethodCodec::decode_method_call.
65static gboolean fl_test_codec_decode_method_call(FlMethodCodec* codec,
66 GBytes* message,
67 gchar** name,
68 FlValue** args,
69 GError** error) {
70 EXPECT_TRUE(FL_IS_TEST_METHOD_CODEC(codec));
71
72 g_autofree gchar* m = message_to_text(message);
73
74 if (strcmp(m, "error") == 0) {
76 "ERROR");
77 return FALSE;
78 } else {
79 *name = g_strdup(m);
81 return TRUE;
82 }
83}
84
85// Implements FlMethodCodec::encode_success_envelope.
86static GBytes* fl_test_codec_encode_success_envelope(FlMethodCodec* codec,
88 GError** error) {
89 EXPECT_TRUE(FL_IS_TEST_METHOD_CODEC(codec));
90
91 g_autofree gchar* text = nullptr;
92 if (result == nullptr || fl_value_get_type(result) == FL_VALUE_TYPE_NULL) {
93 text = g_strdup("(null)");
95 text = g_strdup_printf("%" G_GINT64_FORMAT, fl_value_get_int(result));
96 } else {
98 "ERROR");
99 return nullptr;
100 }
101
102 return text_to_message(text);
103}
104
105// Implements FlMethodCodec::encode_error_envelope.
106static GBytes* fl_test_codec_encode_error_envelope(FlMethodCodec* codec,
107 const gchar* code,
108 const gchar* message,
109 FlValue* details,
110 GError** error) {
111 EXPECT_TRUE(FL_IS_TEST_METHOD_CODEC(codec));
112
113 if (details != nullptr && fl_value_get_type(details) != FL_VALUE_TYPE_INT) {
115 "ERROR");
116 return nullptr;
117 }
118
119 g_autofree gchar* text = nullptr;
120 if (message == nullptr) {
121 if (details == nullptr ||
123 text = g_strdup_printf("Error_%s()", code);
124 } else {
125 text = g_strdup_printf("Error_%s(%" G_GINT64_FORMAT ")", code,
126 fl_value_get_int(details));
127 }
128 } else {
129 if (details == nullptr ||
131 text = g_strdup_printf("Error_%s(%s)", code, message);
132 } else {
133 text = g_strdup_printf("Error_%s(%s,%" G_GINT64_FORMAT ")", code, message,
134 fl_value_get_int(details));
135 }
136 }
137
138 return text_to_message(text);
139}
140
141// Implements FlMethodCodec::decode_response.
142static FlMethodResponse* fl_test_codec_decode_response(FlMethodCodec* codec,
143 GBytes* message,
144 GError** error) {
145 EXPECT_TRUE(FL_IS_TEST_METHOD_CODEC(codec));
146
147 g_autofree gchar* m = message_to_text(message);
148 if (strcmp(m, "codec-error") == 0) {
150 "ERROR");
151 return nullptr;
152 } else if (strcmp(m, "error") == 0) {
153 g_autoptr(FlValue) details = fl_value_new_int(42);
154 return FL_METHOD_RESPONSE(
155 fl_method_error_response_new("code", "message", details));
156 } else {
157 g_autoptr(FlValue) result = fl_value_new_string(m);
158 return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
159 }
160}
161
162static void fl_test_method_codec_class_init(FlTestMethodCodecClass* klass) {
163 FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
165 FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
167 FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
169 FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
171 FL_METHOD_CODEC_CLASS(klass)->decode_response = fl_test_codec_decode_response;
172}
173
174static void fl_test_method_codec_init(FlTestMethodCodec* self) {}
175
176static FlTestMethodCodec* fl_test_method_codec_new() {
177 return FL_TEST_METHOD_CODEC(
178 g_object_new(fl_test_method_codec_get_type(), nullptr));
179}
180
181TEST(FlMethodCodecTest, EncodeMethodCall) {
182 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
183
184 g_autoptr(GError) error = nullptr;
186 FL_METHOD_CODEC(codec), "foo", nullptr, &error);
187 EXPECT_EQ(error, nullptr);
188 EXPECT_NE(message, nullptr);
189
190 g_autofree gchar* message_text = message_to_text(message);
191 EXPECT_STREQ(message_text, "foo()");
192}
193
194TEST(FlMethodCodecTest, EncodeMethodCallEmptyName) {
195 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
196
197 g_autoptr(GError) error = nullptr;
199 FL_METHOD_CODEC(codec), "", nullptr, &error);
200 EXPECT_EQ(error, nullptr);
201 EXPECT_NE(message, nullptr);
202
203 g_autofree gchar* message_text = message_to_text(message);
204 EXPECT_STREQ(message_text, "()");
205}
206
207TEST(FlMethodCodecTest, EncodeMethodCallArgs) {
208 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
209
210 g_autoptr(FlValue) args = fl_value_new_int(42);
211 g_autoptr(GError) error = nullptr;
213 FL_METHOD_CODEC(codec), "foo", args, &error);
214 EXPECT_EQ(error, nullptr);
215 EXPECT_NE(message, nullptr);
216
217 g_autofree gchar* message_text = message_to_text(message);
218 EXPECT_STREQ(message_text, "foo(42)");
219}
220
221TEST(FlMethodCodecTest, EncodeMethodCallError) {
222 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
223
224 g_autoptr(FlValue) args = fl_value_new_bool(FALSE);
225 g_autoptr(GError) error = nullptr;
227 FL_METHOD_CODEC(codec), "foo", args, &error);
228 EXPECT_EQ(message, nullptr);
231}
232
233TEST(FlMethodCodecTest, DecodeMethodCall) {
234 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
235
236 g_autoptr(GBytes) message = text_to_message("foo");
237
238 g_autofree gchar* name = nullptr;
239 g_autoptr(FlValue) args = nullptr;
240 g_autoptr(GError) error = nullptr;
242 FL_METHOD_CODEC(codec), message, &name, &args, &error);
243 EXPECT_EQ(error, nullptr);
245
246 EXPECT_STREQ(name, "foo");
248}
249
250TEST(FlMethodCodecTest, EncodeSuccessEnvelope) {
251 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
252
253 g_autoptr(FlValue) result = fl_value_new_int(42);
254 g_autoptr(GError) error = nullptr;
256 FL_METHOD_CODEC(codec), result, &error);
257 EXPECT_EQ(error, nullptr);
258 EXPECT_NE(message, nullptr);
259
260 g_autofree gchar* message_text = message_to_text(message);
261 EXPECT_STREQ(message_text, "42");
262}
263
264TEST(FlMethodCodecTest, EncodeSuccessEnvelopeEmpty) {
265 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
266
267 g_autoptr(GError) error = nullptr;
269 FL_METHOD_CODEC(codec), nullptr, &error);
270 EXPECT_EQ(error, nullptr);
271 EXPECT_NE(message, nullptr);
272
273 g_autofree gchar* message_text = message_to_text(message);
274 EXPECT_STREQ(message_text, "(null)");
275}
276
277TEST(FlMethodCodecTest, EncodeSuccessEnvelopeError) {
278 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
279
280 g_autoptr(FlValue) result = fl_value_new_string("X");
281 g_autoptr(GError) error = nullptr;
283 FL_METHOD_CODEC(codec), result, &error);
284 EXPECT_EQ(message, nullptr);
287}
288
289TEST(FlMethodCodecTest, EncodeErrorEnvelopeNoMessageOrDetails) {
290 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
291
292 g_autoptr(GError) error = nullptr;
294 FL_METHOD_CODEC(codec), "code", nullptr, nullptr, &error);
295 EXPECT_EQ(error, nullptr);
296 EXPECT_NE(message, nullptr);
297
298 g_autofree gchar* message_text = message_to_text(message);
299 EXPECT_STREQ(message_text, "Error_code()");
300}
301
302TEST(FlMethodCodecTest, EncodeErrorEnvelopeMessage) {
303 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
304
305 g_autoptr(GError) error = nullptr;
307 FL_METHOD_CODEC(codec), "code", "message", nullptr, &error);
308 EXPECT_EQ(error, nullptr);
309 EXPECT_NE(message, nullptr);
310
311 g_autofree gchar* message_text = message_to_text(message);
312 EXPECT_STREQ(message_text, "Error_code(message)");
313}
314
315TEST(FlMethodCodecTest, EncodeErrorEnvelopeDetails) {
316 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
317
318 g_autoptr(FlValue) details = fl_value_new_int(42);
319 g_autoptr(GError) error = nullptr;
321 FL_METHOD_CODEC(codec), "code", nullptr, details, &error);
322 EXPECT_EQ(error, nullptr);
323 EXPECT_NE(message, nullptr);
324
325 g_autofree gchar* message_text = message_to_text(message);
326 EXPECT_STREQ(message_text, "Error_code(42)");
327}
328
329TEST(FlMethodCodecTest, EncodeErrorEnvelopeMessageAndDetails) {
330 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
331
332 g_autoptr(FlValue) details = fl_value_new_int(42);
333 g_autoptr(GError) error = nullptr;
335 FL_METHOD_CODEC(codec), "code", "message", details, &error);
336 EXPECT_EQ(error, nullptr);
337 EXPECT_NE(message, nullptr);
338
339 g_autofree gchar* message_text = message_to_text(message);
340 EXPECT_STREQ(message_text, "Error_code(message,42)");
341}
342
343TEST(FlMethodCodecTest, DecodeResponseSuccess) {
344 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
345
346 g_autoptr(GBytes) message = text_to_message("echo");
347
348 g_autoptr(GError) error = nullptr;
349 g_autoptr(FlMethodResponse) response =
350 fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
351 EXPECT_EQ(error, nullptr);
352 EXPECT_NE(response, nullptr);
353 ASSERT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
355 FL_METHOD_SUCCESS_RESPONSE(response));
356 ASSERT_NE(result, nullptr);
358 EXPECT_STREQ(fl_value_get_string(result), "echo");
359}
360
361TEST(FlMethodCodecTest, DecodeResponseNotImplemented) {
362 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
363
364 g_autoptr(GBytes) message = g_bytes_new(nullptr, 0);
365
366 g_autoptr(GError) error = nullptr;
367 g_autoptr(FlMethodResponse) response =
368 fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
369 EXPECT_EQ(error, nullptr);
370 EXPECT_NE(response, nullptr);
371 ASSERT_TRUE(FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(response));
372}
373
374TEST(FlMethodCodecTest, DecodeResponseCodecError) {
375 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
376
377 g_autoptr(GBytes) message = text_to_message("codec-error");
378
379 g_autoptr(GError) error = nullptr;
380 g_autoptr(FlMethodResponse) response =
381 fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
384 EXPECT_EQ(response, nullptr);
385}
386
387TEST(FlMethodCodecTest, DecodeResponseError) {
388 g_autoptr(FlTestMethodCodec) codec = fl_test_method_codec_new();
389
390 g_autoptr(GBytes) message = text_to_message("error");
391
392 g_autoptr(GError) error = nullptr;
393 g_autoptr(FlMethodResponse) response =
394 fl_method_codec_decode_response(FL_METHOD_CODEC(codec), message, &error);
395 EXPECT_EQ(error, nullptr);
396 EXPECT_NE(response, nullptr);
397 ASSERT_TRUE(FL_METHOD_ERROR_RESPONSE(response));
398 EXPECT_STREQ(
399 fl_method_error_response_get_code(FL_METHOD_ERROR_RESPONSE(response)),
400 "code");
401 EXPECT_STREQ(
402 fl_method_error_response_get_message(FL_METHOD_ERROR_RESPONSE(response)),
403 "message");
404 FlValue* details =
405 fl_method_error_response_get_details(FL_METHOD_ERROR_RESPONSE(response));
406 ASSERT_NE(details, nullptr);
407 ASSERT_EQ(fl_value_get_type(details), FL_VALUE_TYPE_INT);
408 EXPECT_EQ(fl_value_get_int(details), 42);
409}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static gchar * message_to_text(GBytes *message)
@ FL_MESSAGE_CODEC_ERROR_FAILED
#define FL_MESSAGE_CODEC_ERROR
FlMethodResponse * fl_method_codec_decode_response(FlMethodCodec *self, GBytes *message, GError **error)
gboolean fl_method_codec_decode_method_call(FlMethodCodec *self, GBytes *message, gchar **name, FlValue **args, GError **error)
GBytes * fl_method_codec_encode_success_envelope(FlMethodCodec *self, FlValue *result, GError **error)
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
GBytes * fl_method_codec_encode_error_envelope(FlMethodCodec *self, const gchar *code, const gchar *message, FlValue *details, GError **error)
G_DECLARE_FINAL_TYPE(FlTestMethodCodec, fl_test_method_codec, FL, TEST_METHOD_CODEC, FlMethodCodec) struct _FlTestMethodCodec
static void fl_test_method_codec_init(FlTestMethodCodec *self)
static GBytes * fl_test_codec_encode_success_envelope(FlMethodCodec *codec, FlValue *result, GError **error)
static FlTestMethodCodec * fl_test_method_codec_new()
static GBytes * fl_test_codec_encode_error_envelope(FlMethodCodec *codec, const gchar *code, const gchar *message, FlValue *details, GError **error)
static void fl_test_method_codec_class_init(FlTestMethodCodecClass *klass)
static gboolean fl_test_codec_decode_method_call(FlMethodCodec *codec, GBytes *message, gchar **name, FlValue **args, GError **error)
static GBytes * fl_test_codec_encode_method_call(FlMethodCodec *codec, const gchar *name, FlValue *args, GError **error)
static FlMethodResponse * fl_test_codec_decode_response(FlMethodCodec *codec, GBytes *message, GError **error)
static GBytes * text_to_message(const gchar *text)
TEST(FlMethodCodecTest, EncodeMethodCall)
G_DEFINE_TYPE(FlTestMethodCodec, fl_test_method_codec, fl_method_codec_get_type()) static gchar *message_to_text(GBytes *message)
G_MODULE_EXPORT FlValue * fl_method_success_response_get_result(FlMethodSuccessResponse *self)
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
G_MODULE_EXPORT const gchar * fl_method_error_response_get_message(FlMethodErrorResponse *self)
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
G_MODULE_EXPORT FlValue * fl_method_error_response_get_details(FlMethodErrorResponse *self)
G_MODULE_EXPORT const gchar * fl_method_error_response_get_code(FlMethodErrorResponse *self)
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition: fl_value.cc:668
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:69
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:65
@ FL_VALUE_TYPE_INT
Definition: fl_value.h:67
std::u16string text
Win32Message message
return FALSE
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678