15#include "gmock/gmock.h"
16#include "gtest/gtest.h"
20 for (
auto it =
args.begin(); it !=
args.end(); ++it) {
28 for (
auto it =
args.begin(); it !=
args.end(); ++it) {
101 gboolean called = FALSE;
104 messenger,
"flutter/textinput",
"TextInput.setClient",
args,
105 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
107 gboolean* called =
static_cast<gboolean*
>(
user_data);
110 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
114 FL_METHOD_SUCCESS_RESPONSE(response)),
123 gboolean called = FALSE;
126 messenger,
"flutter/textinput",
"TextInput.setEditingState",
args,
127 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
129 gboolean* called =
static_cast<gboolean*
>(
user_data);
132 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
136 FL_METHOD_SUCCESS_RESPONSE(response)),
146 GdkEvent* gdk_event = gdk_event_new(GDK_KEY_PRESS);
147 gdk_event->key.keyval = keyval;
148 gdk_event->key.state = state;
153TEST(FlTextInputHandlerTest, MessageHandler) {
155 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
167TEST(FlTextInputHandlerTest, SetClient) {
169 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
180TEST(FlTextInputHandlerTest, Show) {
182 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
190 gboolean called = FALSE;
192 messenger,
"flutter/textinput",
"TextInput.show",
nullptr,
193 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
195 gboolean* called =
static_cast<gboolean*
>(
user_data);
198 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
202 FL_METHOD_SUCCESS_RESPONSE(response)),
211TEST(FlTextInputHandlerTest, Hide) {
213 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
221 gboolean called = FALSE;
223 messenger,
"flutter/textinput",
"TextInput.hide",
nullptr,
224 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
226 gboolean* called =
static_cast<gboolean*
>(
user_data);
229 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
233 FL_METHOD_SUCCESS_RESPONSE(response)),
242TEST(FlTextInputHandlerTest, ClearClient) {
244 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
250 gboolean called = FALSE;
252 messenger,
"flutter/textinput",
"TextInput.clearClient",
nullptr,
253 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
255 gboolean* called =
static_cast<gboolean*
>(
user_data);
258 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
262 FL_METHOD_SUCCESS_RESPONSE(response)),
271TEST(FlTextInputHandlerTest, PerformAction) {
273 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
281 .input_type =
"TextInputType.multiline",
282 .input_action =
"TextInputAction.newline",
287 .selection_extent = 7,
293 messenger,
"flutter/textinput",
294 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
296 int* call_count =
static_cast<int*
>(
user_data);
298 if (strcmp(
name,
"TextInputClient.updateEditingState") == 0) {
304 .selection_extent = 8,
308 EXPECT_EQ(*call_count, 0);
310 }
else if (strcmp(
name,
"TextInputClient.performAction") == 0) {
316 EXPECT_EQ(*call_count, 1);
325 EXPECT_EQ(call_count, 2);
331TEST(FlTextInputHandlerTest, MultilineWithSendAction) {
333 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
341 .input_type =
"TextInputType.multiline",
342 .input_action =
"TextInputAction.send",
347 .selection_extent = 7,
357 messenger,
"flutter/textinput",
358 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
360 int* call_count =
static_cast<int*
>(
user_data);
362 EXPECT_STREQ(
name,
"TextInputClient.performAction");
364 switch (*call_count) {
373 g_assert_not_reached();
384 EXPECT_EQ(call_count, 1);
389TEST(FlTextInputHandlerTest, MoveCursor) {
391 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
401 .selection_extent = 4,
406 messenger,
"flutter/textinput",
407 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
409 int* call_count =
static_cast<int*
>(
user_data);
411 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
413 switch (*call_count) {
421 .selection_extent = 0,
432 .selection_extent = 7,
437 g_assert_not_reached();
449 EXPECT_EQ(call_count, 2);
454TEST(FlTextInputHandlerTest, Select) {
456 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
466 .selection_extent = 4,
471 messenger,
"flutter/textinput",
472 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
474 int* call_count =
static_cast<int*
>(
user_data);
476 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
478 switch (*call_count) {
486 .selection_extent = 7,
497 .selection_extent = 0,
502 g_assert_not_reached();
514 EXPECT_EQ(call_count, 2);
519TEST(FlTextInputHandlerTest, Composing) {
521 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
529 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
530 ::testing::A<gint*>()))
532 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter")),
533 ::testing::SetArgPointee<3>(0)));
537 messenger,
"flutter/textinput",
538 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
540 int* call_count =
static_cast<int*
>(
user_data);
542 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
544 switch (*call_count) {
551 .selection_extent = 0,
553 .composing_extent = 7,
564 .selection_extent = 6,
575 .selection_extent = 6,
580 g_assert_not_reached();
591 "preedit-start",
nullptr);
593 "preedit-changed",
nullptr);
597 "preedit-end",
nullptr);
598 EXPECT_EQ(call_count, 3);
603TEST(FlTextInputHandlerTest, SurroundingText) {
605 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
615 .selection_extent = 3,
620 ::testing::_, ::testing::StrEq(
"Flutter"), -1, 3));
622 gboolean retrieved =
false;
624 "retrieve-surrounding", &retrieved,
nullptr);
625 EXPECT_TRUE(retrieved);
629 messenger,
"flutter/textinput",
630 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
632 int* call_count =
static_cast<int*
>(
user_data);
634 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
636 switch (*call_count) {
644 .selection_extent = 3,
649 g_assert_not_reached();
659 gboolean deleted =
false;
661 "delete-surrounding", 1, 2, &deleted,
nullptr);
662 EXPECT_TRUE(deleted);
663 EXPECT_EQ(call_count, 1);
668TEST(FlTextInputHandlerTest, SetMarkedTextRect) {
670 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
677 "preedit-start",
nullptr);
703 gboolean called = FALSE;
705 messenger,
"flutter/textinput",
"TextInput.setEditableSizeAndTransform",
707 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
709 gboolean* called =
static_cast<gboolean*
>(
user_data);
712 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
716 FL_METHOD_SUCCESS_RESPONSE(response)),
723 ::testing::_, ::testing::_, ::testing::Eq(27),
724 ::testing::Eq(32), ::testing::_, ::testing::_))
725 .WillOnce(::testing::DoAll(::testing::SetArgPointee<4>(123),
726 ::testing::SetArgPointee<5>(456),
727 ::testing::Return(
true)));
731 ::testing::Pointee(::testing::AllOf(
732 ::testing::Field(&GdkRectangle::x, 123),
733 ::testing::Field(&GdkRectangle::y, 456),
734 ::testing::Field(&GdkRectangle::width, 0),
735 ::testing::Field(&GdkRectangle::height, 0)))));
746 messenger,
"flutter/textinput",
"TextInput.setMarkedTextRect", rect,
747 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
749 gboolean* called =
static_cast<gboolean*
>(
user_data);
752 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
756 FL_METHOD_SUCCESS_RESPONSE(response)),
765TEST(FlTextInputHandlerTest, TextInputTypeNone) {
767 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
775 .input_type =
"TextInputType.none",
781 gboolean called = FALSE;
783 messenger,
"flutter/textinput",
"TextInput.show",
nullptr,
784 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
786 gboolean* called =
static_cast<gboolean*
>(
user_data);
789 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
793 FL_METHOD_SUCCESS_RESPONSE(response)),
802TEST(FlTextInputHandlerTest, TextEditingDelta) {
804 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
812 .enable_delta_model =
true,
817 .selection_extent = 7,
823 messenger,
"flutter/textinput",
824 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
826 int* call_count =
static_cast<int*
>(
user_data);
828 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
830 switch (*call_count) {
838 .old_text =
"Flutter",
839 .delta_text =
"Flutter",
843 .selection_extent = 0,
850 g_assert_not_reached();
861 EXPECT_EQ(call_count, 1);
866TEST(FlTextInputHandlerTest, ComposingDelta) {
868 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
877 .enable_delta_model =
true,
881 "preedit-start",
nullptr);
885 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
886 ::testing::A<gint*>()))
888 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter ")),
889 ::testing::SetArgPointee<3>(8)));
893 messenger,
"flutter/textinput",
894 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
896 int* call_count =
static_cast<int*
>(
user_data);
898 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
900 switch (*call_count) {
909 .delta_text =
"Flutter ",
913 .selection_extent = 8,
915 .composing_extent = 8,
929 .old_text =
"Flutter ",
930 .delta_text =
"Flutter engine",
933 .selection_base = 14,
934 .selection_extent = 14,
935 .composing_base = -1,
936 .composing_extent = -1,
950 .old_text =
"Flutter engine",
951 .selection_base = 14,
952 .selection_extent = 14,
959 g_assert_not_reached();
970 "preedit-changed",
nullptr);
972 "Flutter engine",
nullptr);
974 "preedit-end",
nullptr);
975 EXPECT_EQ(call_count, 3);
980TEST(FlTextInputHandlerTest, NonComposingDelta) {
982 ::testing::NiceMock<flutter::testing::MockGtk> mock_gtk;
991 .enable_delta_model =
true,
996 messenger,
"flutter/textinput",
997 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
999 int* call_count =
static_cast<int*
>(
user_data);
1001 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
1003 switch (*call_count) {
1016 .selection_base = 1,
1017 .selection_extent = 1,
1018 .composing_base = -1,
1019 .composing_extent = -1,
1037 .selection_base = 2,
1038 .selection_extent = 2,
1039 .composing_base = -1,
1040 .composing_extent = -1,
1058 .selection_base = 3,
1059 .selection_extent = 3,
1060 .composing_base = -1,
1061 .composing_extent = -1,
1079 .selection_base = 4,
1080 .selection_extent = 4,
1081 .composing_base = -1,
1082 .composing_extent = -1,
1100 .selection_base = 5,
1101 .selection_extent = 5,
1102 .composing_base = -1,
1103 .composing_extent = -1,
1117 .old_text =
"Flutt",
1121 .selection_base = 6,
1122 .selection_extent = 6,
1123 .composing_base = -1,
1124 .composing_extent = -1,
1138 .old_text =
"Flutte",
1142 .selection_base = 7,
1143 .selection_extent = 7,
1144 .composing_base = -1,
1145 .composing_extent = -1,
1152 g_assert_not_reached();
1176 EXPECT_EQ(call_count, 7);
void fl_binary_messenger_shutdown(FlBinaryMessenger *self)
g_autoptr(GMutexLocker) locker
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent * fl_key_event_new_from_gdk_event(GdkEvent *event)
G_MODULE_EXPORT FlValue * fl_method_success_response_get_result(FlMethodSuccessResponse *self)
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
gboolean fl_mock_binary_messenger_has_handler(FlMockBinaryMessenger *self, const gchar *channel)
void fl_mock_binary_messenger_invoke_json_method(FlMockBinaryMessenger *self, const gchar *channel, const char *name, FlValue *args, FlMockBinaryMessengerMethodCallback callback, gpointer user_data)
const gchar FlBinaryMessengerMessageHandler handler
FlMockBinaryMessenger * fl_mock_binary_messenger_new()
void fl_mock_binary_messenger_set_json_method_channel(FlMockBinaryMessenger *self, const gchar *channel, FlMockBinaryMessengerMethodChannelHandler handler, gpointer user_data)
GtkIMContext * fl_text_input_handler_get_im_context(FlTextInputHandler *self)
FlTextInputHandler * fl_text_input_handler_new(FlBinaryMessenger *messenger)
gboolean fl_text_input_handler_filter_keypress(FlTextInputHandler *self, FlKeyEvent *event)
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
static FlValue * build_input_config(InputConfig config)
static void set_client(FlMockBinaryMessenger *messenger, InputConfig config)
static FlValue * build_editing_state(EditingState state)
static FlValue * build_map(std::map< const gchar *, FlValue * > args)
static FlValue * build_list(std::vector< FlValue * > args)
TEST(FlTextInputHandlerTest, MessageHandler)
static void set_editing_state(FlMockBinaryMessenger *messenger, EditingState state)
static FlValue * build_editing_delta(EditingDelta delta)
G_MODULE_EXPORT FlValue * fl_value_new_map()
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
G_MODULE_EXPORT FlValue * fl_value_new_null()
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
G_MODULE_EXPORT FlValue * fl_value_new_list()
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
typedefG_BEGIN_DECLS struct _FlValue FlValue
FlutterKeyEvent key_event
void gtk_im_context_focus_in(GtkIMContext *context)
void gtk_im_context_set_cursor_location(GtkIMContext *context, const GdkRectangle *area)
void gtk_im_context_focus_out(GtkIMContext *context)
void gtk_im_context_get_preedit_string(GtkIMContext *context, gchar **str, PangoAttrList **attrs, gint *cursor_pos)
void gtk_im_context_set_surrounding(GtkIMContext *context, const gchar *text, gint len, gint cursor_index)
gboolean gtk_widget_translate_coordinates(GtkWidget *src_widget, GtkWidget *dest_widget, gint src_x, gint src_y, gint *dest_x, gint *dest_y)