Make a mock messenger that can easily mock channels (flutter/engine#56867)
The previous mock required knowing the specific functions used in the binary messenger, this method instead allows test code to provide complete platform channel implementation for testing and make simulated platform channel calls into embedder code.
This commit is contained in:
parent
3cb4a84de6
commit
14ae687eac
@ -249,11 +249,10 @@ executable("flutter_linux_unittests") {
|
||||
"fl_view_test.cc",
|
||||
"fl_window_state_monitor_test.cc",
|
||||
"key_mapping_test.cc",
|
||||
"testing/fl_mock_binary_messenger.cc",
|
||||
"testing/fl_test.cc",
|
||||
"testing/fl_test_gtk_logs.cc",
|
||||
"testing/fl_test_gtk_logs.h",
|
||||
"testing/mock_binary_messenger.cc",
|
||||
"testing/mock_binary_messenger_response_handle.cc",
|
||||
"testing/mock_engine.cc",
|
||||
"testing/mock_epoxy.cc",
|
||||
"testing/mock_im_context.cc",
|
||||
|
@ -16,9 +16,34 @@
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_renderer.h"
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlFakeBinaryMessengerResponseHandle,
|
||||
fl_fake_binary_messenger_response_handle,
|
||||
FL,
|
||||
FAKE_BINARY_MESSENGER_RESPONSE_HANDLE,
|
||||
FlBinaryMessengerResponseHandle)
|
||||
|
||||
struct _FlFakeBinaryMessengerResponseHandle {
|
||||
FlBinaryMessengerResponseHandle parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlFakeBinaryMessengerResponseHandle,
|
||||
fl_fake_binary_messenger_response_handle,
|
||||
fl_binary_messenger_response_handle_get_type());
|
||||
|
||||
static void fl_fake_binary_messenger_response_handle_class_init(
|
||||
FlFakeBinaryMessengerResponseHandleClass* klass) {}
|
||||
|
||||
static void fl_fake_binary_messenger_response_handle_init(
|
||||
FlFakeBinaryMessengerResponseHandle* self) {}
|
||||
|
||||
FlFakeBinaryMessengerResponseHandle*
|
||||
fl_fake_binary_messenger_response_handle_new() {
|
||||
return FL_FAKE_BINARY_MESSENGER_RESPONSE_HANDLE(
|
||||
g_object_new(fl_fake_binary_messenger_response_handle_get_type(), NULL));
|
||||
}
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlFakeBinaryMessenger,
|
||||
fl_fake_binary_messenger,
|
||||
FL,
|
||||
@ -55,7 +80,7 @@ static gboolean send_message_cb(gpointer user_data) {
|
||||
g_autoptr(GBytes) message = g_bytes_new(text, strlen(text));
|
||||
self->message_handler(FL_BINARY_MESSENGER(self), "CHANNEL", message,
|
||||
FL_BINARY_MESSENGER_RESPONSE_HANDLE(
|
||||
fl_mock_binary_messenger_response_handle_new()),
|
||||
fl_fake_binary_messenger_response_handle_new()),
|
||||
self->message_handler_user_data);
|
||||
|
||||
return FALSE;
|
||||
@ -83,7 +108,7 @@ static gboolean send_response(FlBinaryMessenger* messenger,
|
||||
GError** error) {
|
||||
FlFakeBinaryMessenger* self = FL_FAKE_BINARY_MESSENGER(messenger);
|
||||
|
||||
EXPECT_TRUE(FL_IS_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle));
|
||||
EXPECT_TRUE(FL_IS_FAKE_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle));
|
||||
|
||||
g_autofree gchar* text =
|
||||
g_strndup(static_cast<const gchar*>(g_bytes_get_data(response, nullptr)),
|
||||
|
@ -94,8 +94,6 @@ struct _FlKeyChannelResponder {
|
||||
GObject parent_instance;
|
||||
|
||||
FlBasicMessageChannel* channel;
|
||||
|
||||
FlKeyChannelResponderMock* mock;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlKeyChannelResponder, fl_key_channel_responder, G_TYPE_OBJECT)
|
||||
@ -117,9 +115,6 @@ static void handle_response(GObject* object,
|
||||
FlBasicMessageChannel* messageChannel = FL_BASIC_MESSAGE_CHANNEL(object);
|
||||
FlValue* message =
|
||||
fl_basic_message_channel_send_finish(messageChannel, result, &error);
|
||||
if (self->mock != nullptr && self->mock->value_converter != nullptr) {
|
||||
message = self->mock->value_converter(message);
|
||||
}
|
||||
bool handled = false;
|
||||
if (error != nullptr) {
|
||||
g_warning("Unable to retrieve framework response: %s", error->message);
|
||||
@ -152,22 +147,16 @@ static void fl_key_channel_responder_init(FlKeyChannelResponder* self) {}
|
||||
|
||||
// Creates a new FlKeyChannelResponder instance, with a messenger used to send
|
||||
// messages to the framework, and an FlTextInputHandler that is used to handle
|
||||
// key events that the framework doesn't handle. Mainly for testing purposes, it
|
||||
// also takes an optional callback to call when a response is received, and an
|
||||
// optional channel name to use when sending messages.
|
||||
// key events that the framework doesn't handle.
|
||||
FlKeyChannelResponder* fl_key_channel_responder_new(
|
||||
FlBinaryMessenger* messenger,
|
||||
FlKeyChannelResponderMock* mock) {
|
||||
FlBinaryMessenger* messenger) {
|
||||
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
|
||||
|
||||
FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(
|
||||
g_object_new(fl_key_channel_responder_get_type(), nullptr));
|
||||
self->mock = mock;
|
||||
|
||||
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
|
||||
const char* channel_name =
|
||||
mock == nullptr ? kChannelName : mock->channel_name;
|
||||
self->channel = fl_basic_message_channel_new(messenger, channel_name,
|
||||
self->channel = fl_basic_message_channel_new(messenger, kChannelName,
|
||||
FL_MESSAGE_CODEC(codec));
|
||||
|
||||
return self;
|
||||
|
@ -11,27 +11,6 @@
|
||||
|
||||
typedef FlValue* (*FlValueConverter)(FlValue*);
|
||||
|
||||
/**
|
||||
* FlKeyChannelResponderMock:
|
||||
*
|
||||
* Allows mocking of FlKeyChannelResponder methods and values. Only used in
|
||||
* unittests.
|
||||
*/
|
||||
typedef struct _FlKeyChannelResponderMock {
|
||||
/**
|
||||
* FlKeyChannelResponderMock::value_converter:
|
||||
* If #value_converter is not nullptr, then this function is applied to the
|
||||
* reply of the message, whose return value is taken as the message reply.
|
||||
*/
|
||||
FlValueConverter value_converter;
|
||||
|
||||
/**
|
||||
* FlKeyChannelResponderMock::channel_name:
|
||||
* Mocks the channel name to send the message.
|
||||
*/
|
||||
const char* channel_name;
|
||||
} FlKeyChannelResponderMock;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlKeyChannelResponder,
|
||||
@ -64,15 +43,13 @@ typedef void (*FlKeyChannelResponderAsyncCallback)(bool handled,
|
||||
/**
|
||||
* fl_key_channel_responder_new:
|
||||
* @messenger: the messenger that the message channel should be built on.
|
||||
* @mock: options to mock several functionalities. Only used in unittests.
|
||||
*
|
||||
* Creates a new #FlKeyChannelResponder.
|
||||
*
|
||||
* Returns: a new #FlKeyChannelResponder.
|
||||
*/
|
||||
FlKeyChannelResponder* fl_key_channel_responder_new(
|
||||
FlBinaryMessenger* messenger,
|
||||
FlKeyChannelResponderMock* mock = nullptr);
|
||||
FlBinaryMessenger* messenger);
|
||||
|
||||
/**
|
||||
* fl_key_channel_responder_handle_event:
|
||||
|
@ -7,64 +7,81 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
|
||||
static const char* expected_value = nullptr;
|
||||
static gboolean expected_handled = FALSE;
|
||||
typedef struct {
|
||||
const gchar* expected_message;
|
||||
gboolean handled;
|
||||
} KeyEventData;
|
||||
|
||||
static FlValue* echo_response_cb(FlValue* echoed_value) {
|
||||
gchar* text = fl_value_to_string(echoed_value);
|
||||
EXPECT_STREQ(text, expected_value);
|
||||
g_free(text);
|
||||
static FlValue* key_event_cb(FlMockBinaryMessenger* messenger,
|
||||
FlValue* message,
|
||||
gpointer user_data) {
|
||||
KeyEventData* data = static_cast<KeyEventData*>(user_data);
|
||||
|
||||
FlValue* value = fl_value_new_map();
|
||||
fl_value_set_string_take(value, "handled",
|
||||
fl_value_new_bool(expected_handled));
|
||||
return value;
|
||||
g_autofree gchar* message_string = fl_value_to_string(message);
|
||||
EXPECT_STREQ(message_string, data->expected_message);
|
||||
|
||||
FlValue* response = fl_value_new_map();
|
||||
fl_value_set_string_take(response, "handled",
|
||||
fl_value_new_bool(data->handled));
|
||||
|
||||
free(data);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static void responder_callback(bool handled, gpointer user_data) {
|
||||
EXPECT_EQ(handled, expected_handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
static void set_key_event_channel(FlMockBinaryMessenger* messenger,
|
||||
const gchar* expected_message,
|
||||
gboolean handled) {
|
||||
KeyEventData* data = g_new0(KeyEventData, 1);
|
||||
data->expected_message = expected_message;
|
||||
data->handled = handled;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/keyevent", key_event_cb, data);
|
||||
}
|
||||
|
||||
// Test sending a letter "A";
|
||||
TEST(FlKeyChannelResponderTest, SendKeyEvent) {
|
||||
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
|
||||
|
||||
g_autoptr(FlEngine) engine = make_mock_engine();
|
||||
g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
|
||||
FlKeyChannelResponderMock mock{
|
||||
.value_converter = echo_response_cb,
|
||||
.channel_name = "test/echo",
|
||||
};
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlKeyChannelResponder) responder =
|
||||
fl_key_channel_responder_new(messenger, &mock);
|
||||
fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
|
||||
|
||||
set_key_event_channel(
|
||||
messenger,
|
||||
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
|
||||
"modifiers: 0, unicodeScalarValues: 65}",
|
||||
FALSE);
|
||||
g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
|
||||
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event1, 0,
|
||||
responder_callback, loop);
|
||||
expected_value =
|
||||
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
|
||||
"modifiers: 0, unicodeScalarValues: 65}";
|
||||
expected_handled = FALSE;
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event1, 0,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_FALSE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
set_key_event_channel(
|
||||
messenger,
|
||||
"{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
|
||||
"modifiers: 0, unicodeScalarValues: 65}",
|
||||
FALSE);
|
||||
g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
|
||||
23456, FALSE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event2, 0,
|
||||
responder_callback, loop);
|
||||
expected_value =
|
||||
"{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
|
||||
"modifiers: 0, unicodeScalarValues: 65}";
|
||||
expected_handled = FALSE;
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event2, 0,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_FALSE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
void test_lock_event(guint key_code,
|
||||
@ -72,34 +89,35 @@ void test_lock_event(guint key_code,
|
||||
const char* up_expected) {
|
||||
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
|
||||
|
||||
g_autoptr(FlEngine) engine = make_mock_engine();
|
||||
g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
|
||||
FlKeyChannelResponderMock mock{
|
||||
.value_converter = echo_response_cb,
|
||||
.channel_name = "test/echo",
|
||||
};
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlKeyChannelResponder) responder =
|
||||
fl_key_channel_responder_new(messenger, &mock);
|
||||
fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
|
||||
|
||||
set_key_event_channel(messenger, down_expected, FALSE);
|
||||
g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
|
||||
12345, TRUE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event1, 0,
|
||||
responder_callback, loop);
|
||||
expected_value = down_expected;
|
||||
expected_handled = FALSE;
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event1, 0,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_FALSE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
expected_value = up_expected;
|
||||
expected_handled = FALSE;
|
||||
set_key_event_channel(messenger, up_expected, FALSE);
|
||||
g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
|
||||
12346, FALSE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event2, 0,
|
||||
responder_callback, loop);
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event2, 0,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_FALSE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
// Test sending a "NumLock" keypress.
|
||||
@ -132,50 +150,52 @@ TEST(FlKeyChannelResponderTest, SendShiftLockKeyEvent) {
|
||||
TEST(FlKeyChannelResponderTest, TestKeyEventHandledByFramework) {
|
||||
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
|
||||
|
||||
g_autoptr(FlEngine) engine = make_mock_engine();
|
||||
g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
|
||||
FlKeyChannelResponderMock mock{
|
||||
.value_converter = echo_response_cb,
|
||||
.channel_name = "test/echo",
|
||||
};
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlKeyChannelResponder) responder =
|
||||
fl_key_channel_responder_new(messenger, &mock);
|
||||
fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
|
||||
|
||||
set_key_event_channel(
|
||||
messenger,
|
||||
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
|
||||
"keyCode: 65, modifiers: 0, unicodeScalarValues: 65}",
|
||||
TRUE);
|
||||
g_autoptr(FlKeyEvent) event = fl_key_event_new(
|
||||
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event, 0, responder_callback,
|
||||
loop);
|
||||
expected_handled = TRUE;
|
||||
expected_value =
|
||||
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
|
||||
"keyCode: 65, modifiers: 0, unicodeScalarValues: 65}";
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event, 0,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_TRUE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlKeyChannelResponderTest, UseSpecifiedLogicalKey) {
|
||||
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
|
||||
|
||||
g_autoptr(FlEngine) engine = make_mock_engine();
|
||||
g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine);
|
||||
FlKeyChannelResponderMock mock{
|
||||
.value_converter = echo_response_cb,
|
||||
.channel_name = "test/echo",
|
||||
};
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlKeyChannelResponder) responder =
|
||||
fl_key_channel_responder_new(messenger, &mock);
|
||||
fl_key_channel_responder_new(FL_BINARY_MESSENGER(messenger));
|
||||
|
||||
g_autoptr(FlKeyEvent) event = fl_key_event_new(
|
||||
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(responder, event, 888,
|
||||
responder_callback, loop);
|
||||
expected_handled = TRUE;
|
||||
expected_value =
|
||||
set_key_event_channel(
|
||||
messenger,
|
||||
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
|
||||
"keyCode: 65, modifiers: 0, unicodeScalarValues: 65, "
|
||||
"specifiedLogicalKey: 888}";
|
||||
|
||||
// Blocks here until echo_response_cb is called.
|
||||
"specifiedLogicalKey: 888}",
|
||||
TRUE);
|
||||
g_autoptr(FlKeyEvent) event = fl_key_event_new(
|
||||
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
|
||||
fl_key_channel_responder_handle_event(
|
||||
responder, event, 888,
|
||||
[](bool handled, gpointer user_data) {
|
||||
EXPECT_TRUE(handled);
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
@ -4,9 +4,10 @@
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_handler.h"
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -26,19 +27,6 @@ G_DECLARE_FINAL_TYPE(FlMockKeyboardHandlerDelegate,
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
MATCHER_P(MethodSuccessResponse, result, "") {
|
||||
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
|
||||
g_autoptr(FlMethodResponse) response =
|
||||
fl_method_codec_decode_response(FL_METHOD_CODEC(codec), arg, nullptr);
|
||||
fl_method_response_get_result(response, nullptr);
|
||||
if (fl_value_equal(fl_method_response_get_result(response, nullptr),
|
||||
result)) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << ::testing::PrintToString(response);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct _FlMockKeyboardHandlerDelegate {
|
||||
GObject parent_instance;
|
||||
};
|
||||
@ -74,8 +62,7 @@ static FlMockKeyboardHandlerDelegate* fl_mock_keyboard_handler_delegate_new() {
|
||||
}
|
||||
|
||||
TEST(FlKeyboardHandlerTest, KeyboardChannelGetPressedState) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlEngine) engine =
|
||||
FL_ENGINE(g_object_new(fl_engine_get_type(), "binary-messenger",
|
||||
FL_BINARY_MESSENGER(messenger), nullptr));
|
||||
@ -95,21 +82,28 @@ TEST(FlKeyboardHandlerTest, KeyboardChannelGetPressedState) {
|
||||
},
|
||||
nullptr);
|
||||
g_autoptr(FlKeyboardHandler) handler =
|
||||
fl_keyboard_handler_new(messenger, manager);
|
||||
fl_keyboard_handler_new(FL_BINARY_MESSENGER(messenger), manager);
|
||||
EXPECT_NE(handler, nullptr);
|
||||
|
||||
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
|
||||
g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
|
||||
FL_METHOD_CODEC(codec), kGetKeyboardStateMethod, nullptr, nullptr);
|
||||
gboolean called = FALSE;
|
||||
fl_mock_binary_messenger_invoke_standard_method(
|
||||
messenger, kKeyboardChannelName, kGetKeyboardStateMethod, nullptr,
|
||||
[](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
g_autoptr(FlValue) response = fl_value_new_map();
|
||||
fl_value_set_take(response, fl_value_new_int(kMockPhysicalKey),
|
||||
fl_value_new_int(kMockLogicalKey));
|
||||
EXPECT_CALL(messenger,
|
||||
fl_binary_messenger_send_response(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger), ::testing::_,
|
||||
MethodSuccessResponse(response), ::testing::_))
|
||||
.WillOnce(::testing::Return(true));
|
||||
EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
|
||||
|
||||
messenger.ReceiveMessage(kKeyboardChannelName, message);
|
||||
g_autoptr(FlValue) expected_result = fl_value_new_map();
|
||||
fl_value_set_take(expected_result, fl_value_new_int(kMockPhysicalKey),
|
||||
fl_value_new_int(kMockLogicalKey));
|
||||
EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result(
|
||||
FL_METHOD_SUCCESS_RESPONSE(response)),
|
||||
expected_result));
|
||||
},
|
||||
&called);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
@ -220,34 +220,13 @@ gboolean fl_method_channel_respond(
|
||||
g_return_val_if_fail(FL_IS_METHOD_CHANNEL(self), FALSE);
|
||||
g_return_val_if_fail(FL_IS_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle),
|
||||
FALSE);
|
||||
g_return_val_if_fail(FL_IS_METHOD_SUCCESS_RESPONSE(response) ||
|
||||
FL_IS_METHOD_ERROR_RESPONSE(response) ||
|
||||
FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(response),
|
||||
FALSE);
|
||||
g_return_val_if_fail(FL_IS_METHOD_RESPONSE(response), FALSE);
|
||||
|
||||
g_autoptr(GBytes) message = nullptr;
|
||||
if (FL_IS_METHOD_SUCCESS_RESPONSE(response)) {
|
||||
FlMethodSuccessResponse* r = FL_METHOD_SUCCESS_RESPONSE(response);
|
||||
message = fl_method_codec_encode_success_envelope(
|
||||
self->codec, fl_method_success_response_get_result(r), error);
|
||||
if (message == nullptr) {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (FL_IS_METHOD_ERROR_RESPONSE(response)) {
|
||||
FlMethodErrorResponse* r = FL_METHOD_ERROR_RESPONSE(response);
|
||||
message = fl_method_codec_encode_error_envelope(
|
||||
self->codec, fl_method_error_response_get_code(r),
|
||||
fl_method_error_response_get_message(r),
|
||||
fl_method_error_response_get_details(r), error);
|
||||
if (message == nullptr) {
|
||||
return FALSE;
|
||||
}
|
||||
} else if (FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(response)) {
|
||||
message = nullptr;
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
g_autoptr(GBytes) message =
|
||||
fl_method_codec_encode_response(self->codec, response, error);
|
||||
if (message == nullptr) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return fl_binary_messenger_send_response(self->messenger, response_handle,
|
||||
message, error);
|
||||
}
|
||||
|
@ -59,6 +59,32 @@ GBytes* fl_method_codec_encode_error_envelope(FlMethodCodec* self,
|
||||
self, code, message, details, error);
|
||||
}
|
||||
|
||||
GBytes* fl_method_codec_encode_response(FlMethodCodec* self,
|
||||
FlMethodResponse* response,
|
||||
GError** error) {
|
||||
g_return_val_if_fail(FL_IS_METHOD_CODEC(self), nullptr);
|
||||
g_return_val_if_fail(FL_IS_METHOD_SUCCESS_RESPONSE(response) ||
|
||||
FL_IS_METHOD_ERROR_RESPONSE(response) ||
|
||||
FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(response),
|
||||
nullptr);
|
||||
|
||||
if (FL_IS_METHOD_SUCCESS_RESPONSE(response)) {
|
||||
FlMethodSuccessResponse* r = FL_METHOD_SUCCESS_RESPONSE(response);
|
||||
return fl_method_codec_encode_success_envelope(
|
||||
self, fl_method_success_response_get_result(r), error);
|
||||
} else if (FL_IS_METHOD_ERROR_RESPONSE(response)) {
|
||||
FlMethodErrorResponse* r = FL_METHOD_ERROR_RESPONSE(response);
|
||||
return fl_method_codec_encode_error_envelope(
|
||||
self, fl_method_error_response_get_code(r),
|
||||
fl_method_error_response_get_message(r),
|
||||
fl_method_error_response_get_details(r), error);
|
||||
} else if (FL_IS_METHOD_NOT_IMPLEMENTED_RESPONSE(response)) {
|
||||
return g_bytes_new(nullptr, 0);
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
FlMethodResponse* fl_method_codec_decode_response(FlMethodCodec* self,
|
||||
GBytes* message,
|
||||
GError** error) {
|
||||
|
@ -85,6 +85,21 @@ GBytes* fl_method_codec_encode_error_envelope(FlMethodCodec* codec,
|
||||
FlValue* details,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_method_codec_encode_response:
|
||||
* @codec: an #FlMethodCodec.
|
||||
* @response: response to encode.
|
||||
* @error: (allow-none): #GError location to store the error occurring, or
|
||||
* %NULL.
|
||||
*
|
||||
* Encodes a response to a method call.
|
||||
*
|
||||
* Returns: a new #FlMethodResponse or %NULL on error.
|
||||
*/
|
||||
GBytes* fl_method_codec_encode_response(FlMethodCodec* codec,
|
||||
FlMethodResponse* response,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_method_codec_decode_response:
|
||||
* @codec: an #FlMethodCodec.
|
||||
@ -92,8 +107,7 @@ GBytes* fl_method_codec_encode_error_envelope(FlMethodCodec* codec,
|
||||
* @error: (allow-none): #GError location to store the error occurring, or
|
||||
* %NULL.
|
||||
*
|
||||
* Decodes a response to a method call. If the call resulted in an error then
|
||||
* @error_code is set, otherwise it is %NULL.
|
||||
* Decodes a response to a method call.
|
||||
*
|
||||
* Returns: a new #FlMethodResponse or %NULL on error.
|
||||
*/
|
||||
|
@ -5,90 +5,14 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_platform_handler.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
MATCHER_P(SuccessResponse, result, "") {
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
g_autoptr(FlMethodResponse) response =
|
||||
fl_method_codec_decode_response(FL_METHOD_CODEC(codec), arg, nullptr);
|
||||
if (fl_value_equal(fl_method_response_get_result(response, nullptr),
|
||||
result)) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << ::testing::PrintToString(response);
|
||||
return false;
|
||||
}
|
||||
|
||||
class MethodCallMatcher {
|
||||
public:
|
||||
using is_gtest_matcher = void;
|
||||
|
||||
explicit MethodCallMatcher(::testing::Matcher<std::string> name,
|
||||
::testing::Matcher<FlValue*> args)
|
||||
: name_(std::move(name)), args_(std::move(args)) {}
|
||||
|
||||
bool MatchAndExplain(GBytes* method_call,
|
||||
::testing::MatchResultListener* result_listener) const {
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autofree gchar* name = nullptr;
|
||||
g_autoptr(FlValue) args = nullptr;
|
||||
gboolean result = fl_method_codec_decode_method_call(
|
||||
FL_METHOD_CODEC(codec), method_call, &name, &args, &error);
|
||||
if (!result) {
|
||||
*result_listener << ::testing::PrintToString(error->message);
|
||||
return false;
|
||||
}
|
||||
if (!name_.MatchAndExplain(name, result_listener)) {
|
||||
*result_listener << " where the name doesn't match: \"" << name << "\"";
|
||||
return false;
|
||||
}
|
||||
if (!args_.MatchAndExplain(args, result_listener)) {
|
||||
*result_listener << " where the args don't match: "
|
||||
<< ::testing::PrintToString(args);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DescribeTo(std::ostream* os) const {
|
||||
*os << "method name ";
|
||||
name_.DescribeTo(os);
|
||||
*os << " and args ";
|
||||
args_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const {
|
||||
*os << "method name ";
|
||||
name_.DescribeNegationTo(os);
|
||||
*os << " or args ";
|
||||
args_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
::testing::Matcher<std::string> name_;
|
||||
::testing::Matcher<FlValue*> args_;
|
||||
};
|
||||
|
||||
static ::testing::Matcher<GBytes*> MethodCall(
|
||||
const std::string& name,
|
||||
::testing::Matcher<FlValue*> args) {
|
||||
return MethodCallMatcher(::testing::StrEq(name), std::move(args));
|
||||
}
|
||||
|
||||
MATCHER_P(FlValueEq, value, "equal to " + ::testing::PrintToString(value)) {
|
||||
return fl_value_equal(arg, value);
|
||||
}
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlTestApplication,
|
||||
fl_test_application,
|
||||
FL,
|
||||
@ -116,26 +40,35 @@ static void fl_test_application_startup(GApplication* application) {
|
||||
static void fl_test_application_activate(GApplication* application) {
|
||||
G_APPLICATION_CLASS(fl_test_application_parent_class)->activate(application);
|
||||
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlPlatformHandler) handler = fl_platform_handler_new(messenger);
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlPlatformHandler) handler =
|
||||
fl_platform_handler_new(FL_BINARY_MESSENGER(messenger));
|
||||
EXPECT_NE(handler, nullptr);
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
|
||||
g_autoptr(FlValue) exit_result = fl_value_new_map();
|
||||
fl_value_set_string_take(exit_result, "response",
|
||||
fl_value_new_string("exit"));
|
||||
EXPECT_CALL(messenger,
|
||||
fl_binary_messenger_send_response(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger), ::testing::_,
|
||||
SuccessResponse(exit_result), ::testing::_))
|
||||
.WillOnce(::testing::Return(true));
|
||||
|
||||
// Request app exit.
|
||||
gboolean called = FALSE;
|
||||
g_autoptr(FlValue) args = fl_value_new_map();
|
||||
fl_value_set_string_take(args, "type", fl_value_new_string("required"));
|
||||
g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
|
||||
FL_METHOD_CODEC(codec), "System.exitApplication", args, nullptr);
|
||||
messenger.ReceiveMessage("flutter/platform", message);
|
||||
fl_mock_binary_messenger_invoke_json_method(
|
||||
messenger, "flutter/platform", "System.exitApplication", args,
|
||||
[](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
|
||||
|
||||
g_autoptr(FlValue) expected_result = fl_value_new_map();
|
||||
fl_value_set_string_take(expected_result, "response",
|
||||
fl_value_new_string("exit"));
|
||||
EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result(
|
||||
FL_METHOD_SUCCESS_RESPONSE(response)),
|
||||
expected_result));
|
||||
},
|
||||
&called);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
static void fl_test_application_dispose(GObject* object) {
|
||||
@ -171,59 +104,107 @@ FlTestApplication* fl_test_application_new(gboolean* dispose_called) {
|
||||
}
|
||||
|
||||
TEST(FlPlatformHandlerTest, PlaySound) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
|
||||
g_autoptr(FlPlatformHandler) handler = fl_platform_handler_new(messenger);
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlPlatformHandler) handler =
|
||||
fl_platform_handler_new(FL_BINARY_MESSENGER(messenger));
|
||||
EXPECT_NE(handler, nullptr);
|
||||
|
||||
gboolean called = FALSE;
|
||||
g_autoptr(FlValue) args = fl_value_new_string("SystemSoundType.alert");
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
|
||||
FL_METHOD_CODEC(codec), "SystemSound.play", args, nullptr);
|
||||
fl_mock_binary_messenger_invoke_json_method(
|
||||
messenger, "flutter/platform", "SystemSound.play", args,
|
||||
[](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
g_autoptr(FlValue) null = fl_value_new_null();
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_response(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::_, SuccessResponse(null), ::testing::_))
|
||||
.WillOnce(::testing::Return(true));
|
||||
EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
|
||||
|
||||
messenger.ReceiveMessage("flutter/platform", message);
|
||||
g_autoptr(FlValue) expected_result = fl_value_new_null();
|
||||
EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result(
|
||||
FL_METHOD_SUCCESS_RESPONSE(response)),
|
||||
expected_result));
|
||||
},
|
||||
&called);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlPlatformHandlerTest, ExitApplication) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
|
||||
|
||||
g_autoptr(FlPlatformHandler) handler = fl_platform_handler_new(messenger);
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlPlatformHandler) handler =
|
||||
fl_platform_handler_new(FL_BINARY_MESSENGER(messenger));
|
||||
EXPECT_NE(handler, nullptr);
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
|
||||
g_autoptr(FlValue) null = fl_value_new_null();
|
||||
ON_CALL(messenger, fl_binary_messenger_send_response(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::_, SuccessResponse(null), ::testing::_))
|
||||
.WillByDefault(testing::Return(TRUE));
|
||||
|
||||
// Indicate that the binding is initialized.
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(GBytes) init_message = fl_method_codec_encode_method_call(
|
||||
FL_METHOD_CODEC(codec), "System.initializationComplete", nullptr, &error);
|
||||
messenger.ReceiveMessage("flutter/platform", init_message);
|
||||
gboolean called = FALSE;
|
||||
fl_mock_binary_messenger_invoke_json_method(
|
||||
messenger, "flutter/platform", "System.initializationComplete", nullptr,
|
||||
[](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
g_autoptr(FlValue) request_args = fl_value_new_map();
|
||||
fl_value_set_string_take(request_args, "type",
|
||||
fl_value_new_string("cancelable"));
|
||||
EXPECT_CALL(messenger,
|
||||
fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/platform"),
|
||||
MethodCall("System.requestAppExit", FlValueEq(request_args)),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
|
||||
|
||||
g_autoptr(FlValue) expected_result = fl_value_new_null();
|
||||
EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result(
|
||||
FL_METHOD_SUCCESS_RESPONSE(response)),
|
||||
expected_result));
|
||||
},
|
||||
&called);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
gboolean request_exit_called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_method_channel(
|
||||
messenger, "flutter/platform",
|
||||
[](FlMockBinaryMessenger* messenger, const gchar* name, FlValue* args,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_STREQ(name, "System.requestAppExit");
|
||||
|
||||
g_autoptr(FlValue) expected_args = fl_value_new_map();
|
||||
fl_value_set_string_take(expected_args, "type",
|
||||
fl_value_new_string("cancelable"));
|
||||
EXPECT_TRUE(fl_value_equal(args, expected_args));
|
||||
|
||||
// Cancel so it doesn't try and exit this app (i.e. the current test)
|
||||
g_autoptr(FlValue) result = fl_value_new_map();
|
||||
fl_value_set_string_take(result, "response",
|
||||
fl_value_new_string("cancel"));
|
||||
return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
},
|
||||
&request_exit_called);
|
||||
|
||||
g_autoptr(FlValue) args = fl_value_new_map();
|
||||
fl_value_set_string_take(args, "type", fl_value_new_string("cancelable"));
|
||||
g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
|
||||
FL_METHOD_CODEC(codec), "System.exitApplication", args, nullptr);
|
||||
messenger.ReceiveMessage("flutter/platform", message);
|
||||
fl_mock_binary_messenger_invoke_json_method(
|
||||
messenger, "flutter/platform", "System.exitApplication", args,
|
||||
[](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
|
||||
gpointer user_data) {
|
||||
EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
|
||||
|
||||
g_autoptr(FlValue) expected_result = fl_value_new_map();
|
||||
fl_value_set_string_take(expected_result, "response",
|
||||
fl_value_new_string("cancel"));
|
||||
EXPECT_TRUE(fl_value_equal(fl_method_success_response_get_result(
|
||||
FL_METHOD_SUCCESS_RESPONSE(response)),
|
||||
expected_result));
|
||||
|
||||
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
|
||||
},
|
||||
loop);
|
||||
|
||||
g_main_loop_run(loop);
|
||||
|
||||
EXPECT_TRUE(request_exit_called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlPlatformHandlerTest, ExitApplicationDispose) {
|
||||
|
@ -5,114 +5,187 @@
|
||||
#include "flutter/shell/platform/linux/fl_settings_handler.h"
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_settings.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
MATCHER_P2(HasSetting, key, value, "") {
|
||||
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
|
||||
g_autoptr(FlValue) message =
|
||||
fl_message_codec_decode_message(FL_MESSAGE_CODEC(codec), arg, nullptr);
|
||||
if (fl_value_equal(fl_value_lookup_string(message, key), value)) {
|
||||
return true;
|
||||
}
|
||||
*result_listener << ::testing::PrintToString(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define EXPECT_SETTING(messenger, key, value) \
|
||||
EXPECT_CALL( \
|
||||
messenger, \
|
||||
fl_binary_messenger_send_on_channel( \
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger), \
|
||||
::testing::StrEq("flutter/settings"), HasSetting(key, value), \
|
||||
::testing::A<GCancellable*>(), ::testing::A<GAsyncReadyCallback>(), \
|
||||
::testing::A<gpointer>()))
|
||||
|
||||
TEST(FlSettingsHandlerTest, AlwaysUse24HourFormat) {
|
||||
::testing::NiceMock<flutter::testing::MockSettings> settings;
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlEngine) engine =
|
||||
FL_ENGINE(g_object_new(fl_engine_get_type(), "binary-messenger",
|
||||
FL_BINARY_MESSENGER(messenger), nullptr));
|
||||
g_autoptr(FlSettingsHandler) handler = fl_settings_handler_new(engine);
|
||||
|
||||
g_autoptr(FlValue) use_12h = fl_value_new_bool(false);
|
||||
g_autoptr(FlValue) use_24h = fl_value_new_bool(true);
|
||||
|
||||
EXPECT_CALL(settings, fl_settings_get_clock_format(
|
||||
::testing::Eq<FlSettings*>(settings)))
|
||||
.WillOnce(::testing::Return(FL_CLOCK_FORMAT_12H))
|
||||
.WillOnce(::testing::Return(FL_CLOCK_FORMAT_24H));
|
||||
|
||||
EXPECT_SETTING(messenger, "alwaysUse24HourFormat", use_12h);
|
||||
gboolean called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value =
|
||||
fl_value_lookup_string(message, "alwaysUse24HourFormat");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
|
||||
EXPECT_FALSE(fl_value_get_bool(value));
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_handler_start(handler, settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
EXPECT_SETTING(messenger, "alwaysUse24HourFormat", use_24h);
|
||||
called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value =
|
||||
fl_value_lookup_string(message, "alwaysUse24HourFormat");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
|
||||
EXPECT_TRUE(fl_value_get_bool(value));
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_emit_changed(settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlSettingsHandlerTest, PlatformBrightness) {
|
||||
::testing::NiceMock<flutter::testing::MockSettings> settings;
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlEngine) engine =
|
||||
FL_ENGINE(g_object_new(fl_engine_get_type(), "binary-messenger",
|
||||
FL_BINARY_MESSENGER(messenger), nullptr));
|
||||
g_autoptr(FlSettingsHandler) handler = fl_settings_handler_new(engine);
|
||||
|
||||
g_autoptr(FlValue) light = fl_value_new_string("light");
|
||||
g_autoptr(FlValue) dark = fl_value_new_string("dark");
|
||||
|
||||
EXPECT_CALL(settings, fl_settings_get_color_scheme(
|
||||
::testing::Eq<FlSettings*>(settings)))
|
||||
.WillOnce(::testing::Return(FL_COLOR_SCHEME_LIGHT))
|
||||
.WillOnce(::testing::Return(FL_COLOR_SCHEME_DARK));
|
||||
|
||||
EXPECT_SETTING(messenger, "platformBrightness", light);
|
||||
gboolean called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value = fl_value_lookup_string(message, "platformBrightness");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
|
||||
EXPECT_STREQ(fl_value_get_string(value), "light");
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_handler_start(handler, settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
EXPECT_SETTING(messenger, "platformBrightness", dark);
|
||||
called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value = fl_value_lookup_string(message, "platformBrightness");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
|
||||
EXPECT_STREQ(fl_value_get_string(value), "dark");
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_emit_changed(settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlSettingsHandlerTest, TextScaleFactor) {
|
||||
::testing::NiceMock<flutter::testing::MockSettings> settings;
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
g_autoptr(FlEngine) engine =
|
||||
FL_ENGINE(g_object_new(fl_engine_get_type(), "binary-messenger",
|
||||
FL_BINARY_MESSENGER(messenger), nullptr));
|
||||
g_autoptr(FlSettingsHandler) handler = fl_settings_handler_new(engine);
|
||||
|
||||
g_autoptr(FlValue) one = fl_value_new_float(1.0);
|
||||
g_autoptr(FlValue) two = fl_value_new_float(2.0);
|
||||
|
||||
EXPECT_CALL(settings, fl_settings_get_text_scaling_factor(
|
||||
::testing::Eq<FlSettings*>(settings)))
|
||||
.WillOnce(::testing::Return(1.0))
|
||||
.WillOnce(::testing::Return(2.0));
|
||||
|
||||
EXPECT_SETTING(messenger, "textScaleFactor", one);
|
||||
gboolean called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value = fl_value_lookup_string(message, "textScaleFactor");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
|
||||
EXPECT_EQ(fl_value_get_float(value), 1.0);
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_handler_start(handler, settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
EXPECT_SETTING(messenger, "textScaleFactor", two);
|
||||
called = FALSE;
|
||||
fl_mock_binary_messenger_set_json_message_channel(
|
||||
messenger, "flutter/settings",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
|
||||
EXPECT_EQ(fl_value_get_type(message), FL_VALUE_TYPE_MAP);
|
||||
FlValue* value = fl_value_lookup_string(message, "textScaleFactor");
|
||||
EXPECT_NE(value, nullptr);
|
||||
EXPECT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
|
||||
EXPECT_EQ(fl_value_get_float(value), 2.0);
|
||||
|
||||
return fl_value_new_null();
|
||||
},
|
||||
&called);
|
||||
fl_settings_emit_changed(settings);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
// MOCK_ENGINE_PROC is leaky by design
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,254 +3,287 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_window_state_monitor.h"
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_test.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_window.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Matches if a FlValue is a the supplied string.
|
||||
class FlValueStringMatcher {
|
||||
public:
|
||||
using is_gtest_matcher = void;
|
||||
|
||||
explicit FlValueStringMatcher(::testing::Matcher<std::string> value)
|
||||
: value_(std::move(value)) {}
|
||||
|
||||
bool MatchAndExplain(GBytes* data,
|
||||
::testing::MatchResultListener* result_listener) const {
|
||||
g_autoptr(FlStringCodec) codec = fl_string_codec_new();
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(FlValue) value =
|
||||
fl_message_codec_decode_message(FL_MESSAGE_CODEC(codec), data, &error);
|
||||
if (value == nullptr) {
|
||||
*result_listener << ::testing::PrintToString(error->message);
|
||||
return false;
|
||||
}
|
||||
if (!value_.MatchAndExplain(fl_value_get_string(value), result_listener)) {
|
||||
*result_listener << " where the value doesn't match: \"" << value << "\"";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DescribeTo(std::ostream* os) const {
|
||||
*os << "value ";
|
||||
value_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const {
|
||||
*os << "value ";
|
||||
value_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
::testing::Matcher<std::string> value_;
|
||||
};
|
||||
|
||||
::testing::Matcher<GBytes*> LifecycleString(const std::string& value) {
|
||||
return FlValueStringMatcher(::testing::StrEq(value));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, GainFocus) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(static_cast<GdkWindowState>(0)));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.resumed"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message), "AppLifecycleState.resumed");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = GDK_WINDOW_STATE_FOCUSED}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, LoseFocus) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(GDK_WINDOW_STATE_FOCUSED));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.inactive"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message),
|
||||
"AppLifecycleState.inactive");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = static_cast<GdkWindowState>(0)}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, EnterIconified) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(static_cast<GdkWindowState>(0)));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.hidden"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message), "AppLifecycleState.hidden");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = GDK_WINDOW_STATE_ICONIFIED}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, LeaveIconified) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(GDK_WINDOW_STATE_ICONIFIED));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.inactive"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message),
|
||||
"AppLifecycleState.inactive");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = static_cast<GdkWindowState>(0)}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, LeaveIconifiedFocused) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(GDK_WINDOW_STATE_ICONIFIED));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.resumed"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message), "AppLifecycleState.resumed");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = static_cast<GdkWindowState>(
|
||||
GDK_WINDOW_STATE_FOCUSED)}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, EnterWithdrawn) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(static_cast<GdkWindowState>(0)));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.hidden"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message), "AppLifecycleState.hidden");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = GDK_WINDOW_STATE_WITHDRAWN}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, LeaveWithdrawn) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(GDK_WINDOW_STATE_WITHDRAWN));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.inactive"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message),
|
||||
"AppLifecycleState.inactive");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = static_cast<GdkWindowState>(0)}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
||||
TEST(FlWindowStateMonitorTest, LeaveWithdrawnFocused) {
|
||||
::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
|
||||
g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
|
||||
::testing::NiceMock<flutter::testing::MockWindow> mock_window;
|
||||
|
||||
gtk_init(0, nullptr);
|
||||
|
||||
EXPECT_CALL(mock_window, gdk_window_get_state)
|
||||
.WillOnce(::testing::Return(GDK_WINDOW_STATE_WITHDRAWN));
|
||||
EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
|
||||
::testing::Eq<FlBinaryMessenger*>(messenger),
|
||||
::testing::StrEq("flutter/lifecycle"),
|
||||
LifecycleString("AppLifecycleState.resumed"),
|
||||
::testing::_, ::testing::_, ::testing::_));
|
||||
gboolean called = TRUE;
|
||||
fl_mock_binary_messenger_set_string_message_channel(
|
||||
messenger, "flutter/lifecycle",
|
||||
[](FlMockBinaryMessenger* messenger, FlValue* message,
|
||||
gpointer user_data) {
|
||||
gboolean* called = static_cast<gboolean*>(user_data);
|
||||
*called = TRUE;
|
||||
EXPECT_STREQ(fl_value_get_string(message), "AppLifecycleState.resumed");
|
||||
return fl_value_new_string("");
|
||||
},
|
||||
&called);
|
||||
|
||||
GtkWindow* window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
||||
gtk_widget_show(GTK_WIDGET(window));
|
||||
g_autoptr(FlWindowStateMonitor) monitor =
|
||||
fl_window_state_monitor_new(messenger, window);
|
||||
fl_window_state_monitor_new(FL_BINARY_MESSENGER(messenger), window);
|
||||
|
||||
GdkEvent event = {
|
||||
.window_state = {.new_window_state = static_cast<GdkWindowState>(
|
||||
GDK_WINDOW_STATE_FOCUSED)}};
|
||||
gboolean handled;
|
||||
g_signal_emit_by_name(window, "window-state-event", &event, &handled);
|
||||
EXPECT_TRUE(called);
|
||||
|
||||
fl_binary_messenger_shutdown(FL_BINARY_MESSENGER(messenger));
|
||||
}
|
||||
|
@ -0,0 +1,609 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h"
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlMockBinaryMessengerResponseHandle,
|
||||
fl_mock_binary_messenger_response_handle,
|
||||
FL,
|
||||
MOCK_BINARY_MESSENGER_RESPONSE_HANDLE,
|
||||
FlBinaryMessengerResponseHandle)
|
||||
|
||||
struct _FlMockBinaryMessengerResponseHandle {
|
||||
FlBinaryMessengerResponseHandle parent_instance;
|
||||
|
||||
FlMockBinaryMessengerCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlMockBinaryMessengerResponseHandle,
|
||||
fl_mock_binary_messenger_response_handle,
|
||||
fl_binary_messenger_response_handle_get_type())
|
||||
|
||||
static void fl_mock_binary_messenger_response_handle_class_init(
|
||||
FlMockBinaryMessengerResponseHandleClass* klass) {}
|
||||
|
||||
static void fl_mock_binary_messenger_response_handle_init(
|
||||
FlMockBinaryMessengerResponseHandle* self) {}
|
||||
|
||||
FlMockBinaryMessengerResponseHandle*
|
||||
fl_mock_binary_messenger_response_handle_new(
|
||||
FlMockBinaryMessengerCallback callback,
|
||||
gpointer user_data) {
|
||||
FlMockBinaryMessengerResponseHandle* self =
|
||||
FL_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(g_object_new(
|
||||
fl_mock_binary_messenger_response_handle_get_type(), nullptr));
|
||||
self->callback = callback;
|
||||
self->user_data = user_data;
|
||||
return self;
|
||||
}
|
||||
|
||||
struct _FlMockBinaryMessenger {
|
||||
GObject parent_instance;
|
||||
|
||||
// Handlers the embedder has registered.
|
||||
GHashTable* handlers;
|
||||
|
||||
// Mocked Dart channels.
|
||||
GHashTable* mock_channels;
|
||||
GHashTable* mock_message_channels;
|
||||
GHashTable* mock_method_channels;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
FlMockBinaryMessengerChannelHandler callback;
|
||||
gpointer user_data;
|
||||
} MockChannel;
|
||||
|
||||
static MockChannel* mock_channel_new(
|
||||
FlMockBinaryMessengerChannelHandler callback,
|
||||
gpointer user_data) {
|
||||
MockChannel* channel = g_new0(MockChannel, 1);
|
||||
channel->callback = callback;
|
||||
channel->user_data = user_data;
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void mock_channel_free(MockChannel* channel) {
|
||||
g_free(channel);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FlMessageCodec* codec;
|
||||
FlMockBinaryMessengerMessageChannelHandler callback;
|
||||
gpointer user_data;
|
||||
} MockMessageChannel;
|
||||
|
||||
static MockMessageChannel* mock_message_channel_new(
|
||||
FlMockBinaryMessengerMessageChannelHandler callback,
|
||||
FlMessageCodec* codec,
|
||||
gpointer user_data) {
|
||||
MockMessageChannel* channel = g_new0(MockMessageChannel, 1);
|
||||
channel->codec = FL_MESSAGE_CODEC(g_object_ref(codec));
|
||||
channel->callback = callback;
|
||||
channel->user_data = user_data;
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void mock_message_channel_free(MockMessageChannel* channel) {
|
||||
g_object_unref(channel->codec);
|
||||
g_free(channel);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FlMethodCodec* codec;
|
||||
FlMockBinaryMessengerMethodChannelHandler callback;
|
||||
gpointer user_data;
|
||||
} MockMethodChannel;
|
||||
|
||||
static MockMethodChannel* mock_method_channel_new(
|
||||
FlMockBinaryMessengerMethodChannelHandler callback,
|
||||
FlMethodCodec* codec,
|
||||
gpointer user_data) {
|
||||
MockMethodChannel* channel = g_new0(MockMethodChannel, 1);
|
||||
channel->codec = FL_METHOD_CODEC(g_object_ref(codec));
|
||||
channel->callback = callback;
|
||||
channel->user_data = user_data;
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void mock_method_channel_free(MockMethodChannel* channel) {
|
||||
g_object_unref(channel->codec);
|
||||
g_free(channel);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FlBinaryMessengerMessageHandler callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify destroy_notify;
|
||||
} Handler;
|
||||
|
||||
static Handler* handler_new(FlBinaryMessengerMessageHandler callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify) {
|
||||
Handler* handler = g_new0(Handler, 1);
|
||||
handler->callback = callback;
|
||||
handler->user_data = user_data;
|
||||
handler->destroy_notify = destroy_notify;
|
||||
return handler;
|
||||
}
|
||||
|
||||
static void handler_free(Handler* handler) {
|
||||
if (handler->destroy_notify) {
|
||||
handler->destroy_notify(handler->user_data);
|
||||
}
|
||||
g_free(handler);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_iface_init(
|
||||
FlBinaryMessengerInterface* iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE(
|
||||
FlMockBinaryMessenger,
|
||||
fl_mock_binary_messenger,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
|
||||
fl_mock_binary_messenger_iface_init))
|
||||
|
||||
static void fl_mock_binary_messenger_set_message_handler_on_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
FlBinaryMessengerMessageHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
g_hash_table_insert(self->handlers, g_strdup(channel),
|
||||
handler_new(handler, user_data, destroy_notify));
|
||||
}
|
||||
|
||||
static gboolean fl_mock_binary_messenger_send_response(
|
||||
FlBinaryMessenger* messenger,
|
||||
FlBinaryMessengerResponseHandle* response_handle,
|
||||
GBytes* response,
|
||||
GError** error) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
|
||||
g_return_val_if_fail(
|
||||
FL_IS_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle), FALSE);
|
||||
FlMockBinaryMessengerResponseHandle* handle =
|
||||
FL_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle);
|
||||
|
||||
handle->callback(self, response, handle->user_data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_send_on_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
GBytes* message,
|
||||
GCancellable* cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
g_autoptr(GTask) task = g_task_new(self, cancellable, callback, user_data);
|
||||
|
||||
MockChannel* mock_channel = static_cast<MockChannel*>(
|
||||
g_hash_table_lookup(self->mock_channels, channel));
|
||||
MockMessageChannel* mock_message_channel = static_cast<MockMessageChannel*>(
|
||||
g_hash_table_lookup(self->mock_message_channels, channel));
|
||||
MockMethodChannel* mock_method_channel = static_cast<MockMethodChannel*>(
|
||||
g_hash_table_lookup(self->mock_method_channels, channel));
|
||||
g_autoptr(GBytes) response = nullptr;
|
||||
if (mock_channel != nullptr) {
|
||||
response = mock_channel->callback(self, message, mock_channel->user_data);
|
||||
} else if (mock_message_channel != nullptr) {
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(FlValue) message_value = fl_message_codec_decode_message(
|
||||
mock_message_channel->codec, message, &error);
|
||||
if (message_value == nullptr) {
|
||||
g_warning("Failed to decode message: %s", error->message);
|
||||
} else {
|
||||
g_autoptr(FlValue) response_value = mock_message_channel->callback(
|
||||
self, message_value, mock_message_channel->user_data);
|
||||
response = fl_message_codec_encode_message(mock_message_channel->codec,
|
||||
response_value, &error);
|
||||
if (response == nullptr) {
|
||||
g_warning("Failed to encode message: %s", error->message);
|
||||
}
|
||||
}
|
||||
} else if (mock_method_channel != nullptr) {
|
||||
g_autofree gchar* name = nullptr;
|
||||
g_autoptr(FlValue) args = nullptr;
|
||||
g_autoptr(GError) error = nullptr;
|
||||
if (!fl_method_codec_decode_method_call(mock_method_channel->codec, message,
|
||||
&name, &args, &error)) {
|
||||
g_warning("Failed to decode method call: %s", error->message);
|
||||
} else {
|
||||
g_autoptr(FlMethodResponse) response_value =
|
||||
mock_method_channel->callback(self, name, args,
|
||||
mock_method_channel->user_data);
|
||||
response = fl_method_codec_encode_response(mock_method_channel->codec,
|
||||
response_value, &error);
|
||||
if (response == nullptr) {
|
||||
g_warning("Failed to encode method response: %s", error->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response == nullptr) {
|
||||
response = g_bytes_new(nullptr, 0);
|
||||
}
|
||||
|
||||
g_task_return_pointer(task, g_bytes_ref(response),
|
||||
reinterpret_cast<GDestroyNotify>(g_bytes_unref));
|
||||
}
|
||||
|
||||
static GBytes* fl_mock_binary_messenger_send_on_channel_finish(
|
||||
FlBinaryMessenger* messenger,
|
||||
GAsyncResult* result,
|
||||
GError** error) {
|
||||
return static_cast<GBytes*>(g_task_propagate_pointer(G_TASK(result), error));
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_resize_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
int64_t new_size) {}
|
||||
|
||||
static void fl_mock_binary_messenger_set_warns_on_channel_overflow(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
bool warns) {}
|
||||
|
||||
static void fl_mock_binary_messenger_shutdown(FlBinaryMessenger* messenger) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
g_hash_table_remove_all(self->handlers);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_dispose(GObject* object) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(object);
|
||||
|
||||
g_clear_pointer(&self->mock_channels, g_hash_table_unref);
|
||||
g_clear_pointer(&self->mock_message_channels, g_hash_table_unref);
|
||||
g_clear_pointer(&self->mock_method_channels, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS(fl_mock_binary_messenger_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_class_init(
|
||||
FlMockBinaryMessengerClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_mock_binary_messenger_dispose;
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_iface_init(
|
||||
FlBinaryMessengerInterface* iface) {
|
||||
iface->set_message_handler_on_channel =
|
||||
fl_mock_binary_messenger_set_message_handler_on_channel;
|
||||
iface->send_response = fl_mock_binary_messenger_send_response;
|
||||
iface->send_on_channel = fl_mock_binary_messenger_send_on_channel;
|
||||
iface->send_on_channel_finish =
|
||||
fl_mock_binary_messenger_send_on_channel_finish;
|
||||
iface->resize_channel = fl_mock_binary_messenger_resize_channel;
|
||||
iface->set_warns_on_channel_overflow =
|
||||
fl_mock_binary_messenger_set_warns_on_channel_overflow;
|
||||
iface->shutdown = fl_mock_binary_messenger_shutdown;
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_init(FlMockBinaryMessenger* self) {
|
||||
self->handlers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify)handler_free);
|
||||
|
||||
self->mock_channels = g_hash_table_new_full(
|
||||
g_str_hash, g_str_equal, g_free, (GDestroyNotify)mock_channel_free);
|
||||
self->mock_message_channels =
|
||||
g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify)mock_message_channel_free);
|
||||
self->mock_method_channels =
|
||||
g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify)mock_method_channel_free);
|
||||
}
|
||||
|
||||
FlMockBinaryMessenger* fl_mock_binary_messenger_new() {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(
|
||||
g_object_new(fl_mock_binary_messenger_get_type(), nullptr));
|
||||
return self;
|
||||
}
|
||||
|
||||
gboolean fl_mock_binary_messenger_has_handler(FlMockBinaryMessenger* self,
|
||||
const gchar* channel) {
|
||||
g_return_val_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self), FALSE);
|
||||
return g_hash_table_lookup(self->handlers, channel) != nullptr;
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_hash_table_insert(self->mock_channels, g_strdup(channel),
|
||||
mock_channel_new(handler, user_data));
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMessageCodec* codec,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_hash_table_insert(self->mock_message_channels, g_strdup(channel),
|
||||
mock_message_channel_new(handler, codec, user_data));
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_standard_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
|
||||
return fl_mock_binary_messenger_set_message_channel(
|
||||
self, channel, FL_MESSAGE_CODEC(codec), handler, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_string_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_autoptr(FlStringCodec) codec = fl_string_codec_new();
|
||||
return fl_mock_binary_messenger_set_message_channel(
|
||||
self, channel, FL_MESSAGE_CODEC(codec), handler, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_json_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
|
||||
return fl_mock_binary_messenger_set_message_channel(
|
||||
self, channel, FL_MESSAGE_CODEC(codec), handler, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMethodCodec* codec,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_hash_table_insert(self->mock_method_channels, g_strdup(channel),
|
||||
mock_method_channel_new(handler, codec, user_data));
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_standard_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
|
||||
fl_mock_binary_messenger_set_method_channel(
|
||||
self, channel, FL_METHOD_CODEC(codec), handler, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_set_json_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
fl_mock_binary_messenger_set_method_channel(
|
||||
self, channel, FL_METHOD_CODEC(codec), handler, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_send(FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
GBytes* message,
|
||||
FlMockBinaryMessengerCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
Handler* handler =
|
||||
static_cast<Handler*>(g_hash_table_lookup(self->handlers, channel));
|
||||
if (handler == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
handler->callback(
|
||||
FL_BINARY_MESSENGER(self), channel, message,
|
||||
FL_BINARY_MESSENGER_RESPONSE_HANDLE(
|
||||
fl_mock_binary_messenger_response_handle_new(callback, user_data)),
|
||||
handler->user_data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FlMessageCodec* codec;
|
||||
FlMockBinaryMessengerMessageCallback callback;
|
||||
gpointer user_data;
|
||||
} SendMessageData;
|
||||
|
||||
static SendMessageData* send_message_data_new(
|
||||
FlMessageCodec* codec,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data) {
|
||||
SendMessageData* data = g_new0(SendMessageData, 1);
|
||||
data->codec = FL_MESSAGE_CODEC(g_object_ref(codec));
|
||||
data->callback = callback;
|
||||
data->user_data = user_data;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void send_message_data_free(SendMessageData* data) {
|
||||
g_object_unref(data->codec);
|
||||
free(data);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(SendMessageData, send_message_data_free)
|
||||
|
||||
static void send_message_cb(FlMockBinaryMessenger* self,
|
||||
GBytes* response,
|
||||
gpointer user_data) {
|
||||
g_autoptr(SendMessageData) data = static_cast<SendMessageData*>(user_data);
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(FlValue) response_value =
|
||||
fl_message_codec_decode_message(data->codec, response, &error);
|
||||
if (response_value == nullptr) {
|
||||
g_warning("Failed to decode message response: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
data->callback(self, response_value, data->user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_send_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMessageCodec* codec,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(GBytes) encoded_message =
|
||||
fl_message_codec_encode_message(codec, message, &error);
|
||||
if (encoded_message == nullptr) {
|
||||
g_warning("Failed to encode message: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
fl_mock_binary_messenger_send(
|
||||
self, channel, encoded_message, send_message_cb,
|
||||
send_message_data_new(codec, callback, user_data));
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_send_standard_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
|
||||
fl_mock_binary_messenger_send_message(self, channel, FL_MESSAGE_CODEC(codec),
|
||||
message, callback, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_send_json_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
|
||||
fl_mock_binary_messenger_send_message(self, channel, FL_MESSAGE_CODEC(codec),
|
||||
message, callback, user_data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
FlMethodCodec* codec;
|
||||
FlMockBinaryMessengerMethodCallback callback;
|
||||
gpointer user_data;
|
||||
} InvokeMethodData;
|
||||
|
||||
static InvokeMethodData* invoke_method_data_new(
|
||||
FlMethodCodec* codec,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data) {
|
||||
InvokeMethodData* data = g_new0(InvokeMethodData, 1);
|
||||
data->codec = FL_METHOD_CODEC(g_object_ref(codec));
|
||||
data->callback = callback;
|
||||
data->user_data = user_data;
|
||||
return data;
|
||||
}
|
||||
|
||||
static void invoke_method_data_free(InvokeMethodData* data) {
|
||||
g_object_unref(data->codec);
|
||||
free(data);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(InvokeMethodData, invoke_method_data_free)
|
||||
|
||||
static void invoke_method_cb(FlMockBinaryMessenger* self,
|
||||
GBytes* response,
|
||||
gpointer user_data) {
|
||||
g_autoptr(InvokeMethodData) data = static_cast<InvokeMethodData*>(user_data);
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(FlMethodResponse) method_response =
|
||||
fl_method_codec_decode_response(data->codec, response, &error);
|
||||
if (method_response == nullptr) {
|
||||
g_warning("Failed to decode method response: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
data->callback(self, method_response, data->user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_invoke_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMethodCodec* codec,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
|
||||
g_autoptr(GError) error = nullptr;
|
||||
g_autoptr(GBytes) message =
|
||||
fl_method_codec_encode_method_call(codec, name, args, &error);
|
||||
if (message == nullptr) {
|
||||
g_warning("Failed to encode method call: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
fl_mock_binary_messenger_send(
|
||||
self, channel, message, invoke_method_cb,
|
||||
invoke_method_data_new(codec, callback, user_data));
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_invoke_standard_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
|
||||
fl_mock_binary_messenger_invoke_method(self, channel, FL_METHOD_CODEC(codec),
|
||||
name, args, callback, user_data);
|
||||
}
|
||||
|
||||
void fl_mock_binary_messenger_invoke_json_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(self));
|
||||
g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
|
||||
fl_mock_binary_messenger_invoke_method(self, channel, FL_METHOD_CODEC(codec),
|
||||
name, args, callback, user_data);
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_TESTING_FL_MOCK_BINARY_MESSENGER_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_TESTING_FL_MOCK_BINARY_MESSENGER_H_
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h"
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlMockBinaryMessenger,
|
||||
fl_mock_binary_messenger,
|
||||
FL,
|
||||
MOCK_BINARY_MESSENGER,
|
||||
GObject)
|
||||
|
||||
typedef GBytes* (*FlMockBinaryMessengerChannelHandler)(
|
||||
FlMockBinaryMessenger* messenger,
|
||||
GBytes* message,
|
||||
gpointer user_data);
|
||||
|
||||
typedef FlValue* (*FlMockBinaryMessengerMessageChannelHandler)(
|
||||
FlMockBinaryMessenger* messenger,
|
||||
FlValue* message,
|
||||
gpointer user_data);
|
||||
|
||||
typedef FlMethodResponse* (*FlMockBinaryMessengerMethodChannelHandler)(
|
||||
FlMockBinaryMessenger* messenger,
|
||||
const gchar* name,
|
||||
FlValue* args,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (*FlMockBinaryMessengerCallback)(FlMockBinaryMessenger* messenger,
|
||||
GBytes* response,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (*FlMockBinaryMessengerMessageCallback)(
|
||||
FlMockBinaryMessenger* messenger,
|
||||
FlValue* response,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (*FlMockBinaryMessengerMethodCallback)(
|
||||
FlMockBinaryMessenger* messenger,
|
||||
FlMethodResponse* response,
|
||||
gpointer user_data);
|
||||
|
||||
FlMockBinaryMessenger* fl_mock_binary_messenger_new();
|
||||
|
||||
gboolean fl_mock_binary_messenger_has_handler(FlMockBinaryMessenger* self,
|
||||
const gchar* channel);
|
||||
|
||||
void fl_mock_binary_messenger_set_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMessageCodec* codec,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_standard_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_string_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_json_message_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMessageChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMethodCodec* codec,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_standard_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_set_json_method_channel(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMockBinaryMessengerMethodChannelHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_send(FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
GBytes* message,
|
||||
FlMockBinaryMessengerCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_send_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMessageCodec* codec,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_send_standard_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_send_json_message(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlValue* message,
|
||||
FlMockBinaryMessengerMessageCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_invoke_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
FlMethodCodec* codec,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_invoke_standard_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void fl_mock_binary_messenger_invoke_json_method(
|
||||
FlMockBinaryMessenger* self,
|
||||
const gchar* channel,
|
||||
const char* name,
|
||||
FlValue* args,
|
||||
FlMockBinaryMessengerMethodCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_TESTING_FL_MOCK_BINARY_MESSENGER_H_
|
@ -1,160 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h"
|
||||
|
||||
using namespace flutter::testing;
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlMockBinaryMessenger,
|
||||
fl_mock_binary_messenger,
|
||||
FL,
|
||||
MOCK_BINARY_MESSENGER,
|
||||
GObject)
|
||||
|
||||
struct _FlMockBinaryMessenger {
|
||||
GObject parent_instance;
|
||||
MockBinaryMessenger* mock;
|
||||
};
|
||||
|
||||
static FlBinaryMessenger* fl_mock_binary_messenger_new(
|
||||
MockBinaryMessenger* mock) {
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(
|
||||
g_object_new(fl_mock_binary_messenger_get_type(), nullptr));
|
||||
self->mock = mock;
|
||||
return FL_BINARY_MESSENGER(self);
|
||||
}
|
||||
|
||||
MockBinaryMessenger::MockBinaryMessenger()
|
||||
: instance_(fl_mock_binary_messenger_new(this)) {}
|
||||
|
||||
MockBinaryMessenger::~MockBinaryMessenger() {
|
||||
if (FL_IS_BINARY_MESSENGER(instance_)) {
|
||||
g_clear_object(&instance_);
|
||||
}
|
||||
}
|
||||
|
||||
MockBinaryMessenger::operator FlBinaryMessenger*() {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
bool MockBinaryMessenger::HasMessageHandler(const gchar* channel) const {
|
||||
return message_handlers_.at(channel) != nullptr;
|
||||
}
|
||||
|
||||
void MockBinaryMessenger::SetMessageHandler(
|
||||
const gchar* channel,
|
||||
FlBinaryMessengerMessageHandler handler,
|
||||
gpointer user_data) {
|
||||
message_handlers_[channel] = handler;
|
||||
user_datas_[channel] = user_data;
|
||||
}
|
||||
|
||||
void MockBinaryMessenger::ReceiveMessage(const gchar* channel,
|
||||
GBytes* message) {
|
||||
FlBinaryMessengerMessageHandler handler = message_handlers_[channel];
|
||||
if (response_handles_[channel] == nullptr) {
|
||||
response_handles_[channel] = FL_BINARY_MESSENGER_RESPONSE_HANDLE(
|
||||
fl_mock_binary_messenger_response_handle_new());
|
||||
}
|
||||
handler(instance_, channel, message, response_handles_[channel],
|
||||
user_datas_[channel]);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_iface_init(
|
||||
FlBinaryMessengerInterface* iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE(
|
||||
FlMockBinaryMessenger,
|
||||
fl_mock_binary_messenger,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
|
||||
fl_mock_binary_messenger_iface_init))
|
||||
|
||||
static void fl_mock_binary_messenger_class_init(
|
||||
FlMockBinaryMessengerClass* klass) {}
|
||||
|
||||
static void fl_mock_binary_messenger_set_message_handler_on_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
FlBinaryMessengerMessageHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger));
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
self->mock->SetMessageHandler(channel, handler, user_data);
|
||||
self->mock->fl_binary_messenger_set_message_handler_on_channel(
|
||||
messenger, channel, handler, user_data, destroy_notify);
|
||||
}
|
||||
|
||||
static gboolean fl_mock_binary_messenger_send_response(
|
||||
FlBinaryMessenger* messenger,
|
||||
FlBinaryMessengerResponseHandle* response_handle,
|
||||
GBytes* response,
|
||||
GError** error) {
|
||||
g_return_val_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger), false);
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
return self->mock->fl_binary_messenger_send_response(
|
||||
messenger, response_handle, response, error);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_send_on_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
GBytes* message,
|
||||
GCancellable* cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger));
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
self->mock->fl_binary_messenger_send_on_channel(
|
||||
messenger, channel, message, cancellable, callback, user_data);
|
||||
}
|
||||
|
||||
static GBytes* fl_mock_binary_messenger_send_on_channel_finish(
|
||||
FlBinaryMessenger* messenger,
|
||||
GAsyncResult* result,
|
||||
GError** error) {
|
||||
g_return_val_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger), nullptr);
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
return self->mock->fl_binary_messenger_send_on_channel_finish(messenger,
|
||||
result, error);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_resize_channel(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
int64_t new_size) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger));
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
self->mock->fl_binary_messenger_resize_channel(messenger, channel, new_size);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_set_warns_on_channel_overflow(
|
||||
FlBinaryMessenger* messenger,
|
||||
const gchar* channel,
|
||||
bool warns) {
|
||||
g_return_if_fail(FL_IS_MOCK_BINARY_MESSENGER(messenger));
|
||||
FlMockBinaryMessenger* self = FL_MOCK_BINARY_MESSENGER(messenger);
|
||||
self->mock->fl_binary_messenger_set_warns_on_channel_overflow(messenger,
|
||||
channel, warns);
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_shutdown(FlBinaryMessenger* messenger) {}
|
||||
|
||||
static void fl_mock_binary_messenger_iface_init(
|
||||
FlBinaryMessengerInterface* iface) {
|
||||
iface->set_message_handler_on_channel =
|
||||
fl_mock_binary_messenger_set_message_handler_on_channel;
|
||||
iface->send_response = fl_mock_binary_messenger_send_response;
|
||||
iface->send_on_channel = fl_mock_binary_messenger_send_on_channel;
|
||||
iface->send_on_channel_finish =
|
||||
fl_mock_binary_messenger_send_on_channel_finish;
|
||||
iface->resize_channel = fl_mock_binary_messenger_resize_channel;
|
||||
iface->set_warns_on_channel_overflow =
|
||||
fl_mock_binary_messenger_set_warns_on_channel_overflow;
|
||||
iface->shutdown = fl_mock_binary_messenger_shutdown;
|
||||
}
|
||||
|
||||
static void fl_mock_binary_messenger_init(FlMockBinaryMessenger* self) {}
|
@ -1,91 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
// Mock for FlBinaryMessenger.
|
||||
class MockBinaryMessenger {
|
||||
public:
|
||||
MockBinaryMessenger();
|
||||
~MockBinaryMessenger();
|
||||
|
||||
// This was an existing use of operator overloading. It's against our style
|
||||
// guide but enabling clang tidy on header files is a higher priority than
|
||||
// fixing this.
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator FlBinaryMessenger*();
|
||||
|
||||
MOCK_METHOD(void,
|
||||
fl_binary_messenger_set_message_handler_on_channel,
|
||||
(FlBinaryMessenger * messenger,
|
||||
const gchar* channel,
|
||||
FlBinaryMessengerMessageHandler handler,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify));
|
||||
|
||||
MOCK_METHOD(gboolean,
|
||||
fl_binary_messenger_send_response,
|
||||
(FlBinaryMessenger * messenger,
|
||||
FlBinaryMessengerResponseHandle* response_handle,
|
||||
GBytes* response,
|
||||
GError** error));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
fl_binary_messenger_send_on_channel,
|
||||
(FlBinaryMessenger * messenger,
|
||||
const gchar* channel,
|
||||
GBytes* message,
|
||||
GCancellable* cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data));
|
||||
|
||||
MOCK_METHOD(GBytes*,
|
||||
fl_binary_messenger_send_on_channel_finish,
|
||||
(FlBinaryMessenger * messenger,
|
||||
GAsyncResult* result,
|
||||
GError** error));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
fl_binary_messenger_resize_channel,
|
||||
(FlBinaryMessenger * messenger,
|
||||
const gchar* channel,
|
||||
int64_t new_size));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
fl_binary_messenger_set_warns_on_channel_overflow,
|
||||
(FlBinaryMessenger * messenger,
|
||||
const gchar* channel,
|
||||
bool warns));
|
||||
|
||||
bool HasMessageHandler(const gchar* channel) const;
|
||||
|
||||
void SetMessageHandler(const gchar* channel,
|
||||
FlBinaryMessengerMessageHandler handler,
|
||||
gpointer user_data);
|
||||
|
||||
void ReceiveMessage(const gchar* channel, GBytes* message);
|
||||
|
||||
private:
|
||||
FlBinaryMessenger* instance_ = nullptr;
|
||||
std::unordered_map<std::string, FlBinaryMessengerMessageHandler>
|
||||
message_handlers_;
|
||||
std::unordered_map<std::string, FlBinaryMessengerResponseHandle*>
|
||||
response_handles_;
|
||||
std::unordered_map<std::string, gpointer> user_datas_;
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_H_
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h"
|
||||
|
||||
struct _FlMockBinaryMessengerResponseHandle {
|
||||
FlBinaryMessengerResponseHandle parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlMockBinaryMessengerResponseHandle,
|
||||
fl_mock_binary_messenger_response_handle,
|
||||
fl_binary_messenger_response_handle_get_type());
|
||||
|
||||
static void fl_mock_binary_messenger_response_handle_class_init(
|
||||
FlMockBinaryMessengerResponseHandleClass* klass) {}
|
||||
|
||||
static void fl_mock_binary_messenger_response_handle_init(
|
||||
FlMockBinaryMessengerResponseHandle* self) {}
|
||||
|
||||
FlMockBinaryMessengerResponseHandle*
|
||||
fl_mock_binary_messenger_response_handle_new() {
|
||||
return FL_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE(
|
||||
g_object_new(fl_mock_binary_messenger_response_handle_get_type(), NULL));
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE_H_
|
||||
|
||||
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlMockBinaryMessengerResponseHandle,
|
||||
fl_mock_binary_messenger_response_handle,
|
||||
FL,
|
||||
MOCK_BINARY_MESSENGER_RESPONSE_HANDLE,
|
||||
FlBinaryMessengerResponseHandle)
|
||||
|
||||
FlMockBinaryMessengerResponseHandle*
|
||||
fl_mock_binary_messenger_response_handle_new();
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_TESTING_MOCK_BINARY_MESSENGER_RESPONSE_HANDLE_H_
|
Loading…
x
Reference in New Issue
Block a user