16#include "gmock/gmock.h"
17#include "gtest/gtest.h"
21 for (
auto it =
args.begin(); it !=
args.end(); ++it) {
29 for (
auto it =
args.begin(); it !=
args.end(); ++it) {
102 gboolean called = FALSE;
105 messenger,
"flutter/textinput",
"TextInput.setClient",
args,
106 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
108 gboolean* called =
static_cast<gboolean*
>(
user_data);
111 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
115 FL_METHOD_SUCCESS_RESPONSE(response)),
124 gboolean called = FALSE;
127 messenger,
"flutter/textinput",
"TextInput.setEditingState",
args,
128 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
130 gboolean* called =
static_cast<gboolean*
>(
user_data);
133 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
137 FL_METHOD_SUCCESS_RESPONSE(response)),
147 GdkEvent* gdk_event = gdk_event_new(GDK_KEY_PRESS);
148 gdk_event->key.keyval = keyval;
149 gdk_event->key.state = state;
169 ::testing::NiceMock<flutter::testing::MockGtk>
mock_gtk;
184 gboolean called = FALSE;
186 messenger,
"flutter/textinput",
"TextInput.show",
nullptr,
187 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
189 gboolean* called =
static_cast<gboolean*
>(
user_data);
192 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
196 FL_METHOD_SUCCESS_RESPONSE(response)),
206 gboolean called = FALSE;
208 messenger,
"flutter/textinput",
"TextInput.hide",
nullptr,
209 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
211 gboolean* called =
static_cast<gboolean*
>(
user_data);
214 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
218 FL_METHOD_SUCCESS_RESPONSE(response)),
226 gboolean called = FALSE;
228 messenger,
"flutter/textinput",
"TextInput.clearClient",
nullptr,
229 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
231 gboolean* called =
static_cast<gboolean*
>(
user_data);
234 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
238 FL_METHOD_SUCCESS_RESPONSE(response)),
248 .input_type =
"TextInputType.multiline",
249 .input_action =
"TextInputAction.newline",
254 .selection_extent = 7,
260 messenger,
"flutter/textinput",
261 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
263 int* call_count =
static_cast<int*
>(
user_data);
265 if (strcmp(
name,
"TextInputClient.updateEditingState") == 0) {
271 .selection_extent = 8,
275 EXPECT_EQ(*call_count, 0);
277 }
else if (strcmp(
name,
"TextInputClient.performAction") == 0) {
283 EXPECT_EQ(*call_count, 1);
292 EXPECT_EQ(call_count, 2);
299 .input_type =
"TextInputType.multiline",
300 .input_action =
"TextInputAction.send",
305 .selection_extent = 7,
315 messenger,
"flutter/textinput",
316 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
318 int* call_count =
static_cast<int*
>(
user_data);
320 EXPECT_STREQ(
name,
"TextInputClient.performAction");
322 switch (*call_count) {
331 g_assert_not_reached();
342 EXPECT_EQ(call_count, 1);
350 .selection_extent = 4,
355 messenger,
"flutter/textinput",
356 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
358 int* call_count =
static_cast<int*
>(
user_data);
360 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
362 switch (*call_count) {
370 .selection_extent = 0,
381 .selection_extent = 7,
386 g_assert_not_reached();
398 EXPECT_EQ(call_count, 2);
406 .selection_extent = 4,
411 messenger,
"flutter/textinput",
412 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
414 int* call_count =
static_cast<int*
>(
user_data);
416 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
418 switch (*call_count) {
426 .selection_extent = 7,
437 .selection_extent = 0,
442 g_assert_not_reached();
454 EXPECT_EQ(call_count, 2);
460 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
461 ::testing::A<gint*>()))
463 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter")),
464 ::testing::SetArgPointee<3>(0)));
468 messenger,
"flutter/textinput",
469 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
471 int* call_count =
static_cast<int*
>(
user_data);
473 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
475 switch (*call_count) {
482 .selection_extent = 0,
484 .composing_extent = 7,
495 .selection_extent = 6,
506 .selection_extent = 6,
511 g_assert_not_reached();
522 "preedit-start",
nullptr);
524 "preedit-changed",
nullptr);
528 "preedit-end",
nullptr);
529 EXPECT_EQ(call_count, 3);
537 .selection_extent = 3,
542 ::testing::_, ::testing::StrEq(
"Flutter"), -1, 3));
544 gboolean retrieved =
false;
546 "retrieve-surrounding", &retrieved,
nullptr);
547 EXPECT_TRUE(retrieved);
551 messenger,
"flutter/textinput",
552 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
554 int* call_count =
static_cast<int*
>(
user_data);
556 EXPECT_STREQ(
name,
"TextInputClient.updateEditingState");
558 switch (*call_count) {
566 .selection_extent = 3,
571 g_assert_not_reached();
581 gboolean deleted =
false;
583 "delete-surrounding", 1, 2, &deleted,
nullptr);
584 EXPECT_TRUE(deleted);
585 EXPECT_EQ(call_count, 1);
590 g_object_ref_sink(
window);
594 "preedit-start",
nullptr);
620 gboolean called = FALSE;
622 messenger,
"flutter/textinput",
"TextInput.setEditableSizeAndTransform",
624 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
626 gboolean* called =
static_cast<gboolean*
>(
user_data);
629 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
633 FL_METHOD_SUCCESS_RESPONSE(response)),
640 ::testing::_, ::testing::_, ::testing::Eq(27),
641 ::testing::Eq(32), ::testing::_, ::testing::_))
642 .WillOnce(::testing::DoAll(::testing::SetArgPointee<4>(123),
643 ::testing::SetArgPointee<5>(456),
644 ::testing::Return(
true)));
648 ::testing::Pointee(::testing::AllOf(
649 ::testing::Field(&GdkRectangle::x, 123),
650 ::testing::Field(&GdkRectangle::y, 456),
651 ::testing::Field(&GdkRectangle::width, 0),
652 ::testing::Field(&GdkRectangle::height, 0)))));
663 messenger,
"flutter/textinput",
"TextInput.setMarkedTextRect", rect,
664 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
666 gboolean* called =
static_cast<gboolean*
>(
user_data);
669 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
673 FL_METHOD_SUCCESS_RESPONSE(response)),
687 "preedit-start",
nullptr);
697 gboolean called = FALSE;
699 messenger,
"flutter/textinput",
"TextInput.setMarkedTextRect", rect,
700 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
702 gboolean* called =
static_cast<gboolean*
>(
user_data);
704 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
713 .input_type =
"TextInputType.none",
719 gboolean called = FALSE;
721 messenger,
"flutter/textinput",
"TextInput.show",
nullptr,
722 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
724 gboolean* called =
static_cast<gboolean*
>(
user_data);
727 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
731 FL_METHOD_SUCCESS_RESPONSE(response)),
741 .enable_delta_model =
true,
746 .selection_extent = 7,
752 messenger,
"flutter/textinput",
753 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
755 int* call_count =
static_cast<int*
>(
user_data);
757 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
759 switch (*call_count) {
767 .old_text =
"Flutter",
768 .delta_text =
"Flutter",
772 .selection_extent = 0,
779 g_assert_not_reached();
790 EXPECT_EQ(call_count, 1);
797 .enable_delta_model =
true,
801 "preedit-start",
nullptr);
805 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
806 ::testing::A<gint*>()))
808 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter ")),
809 ::testing::SetArgPointee<3>(8)));
813 messenger,
"flutter/textinput",
814 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
816 int* call_count =
static_cast<int*
>(
user_data);
818 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
820 switch (*call_count) {
829 .delta_text =
"Flutter ",
833 .selection_extent = 8,
835 .composing_extent = 8,
849 .old_text =
"Flutter ",
850 .delta_text =
"Flutter engine",
853 .selection_base = 14,
854 .selection_extent = 14,
855 .composing_base = -1,
856 .composing_extent = -1,
870 .old_text =
"Flutter engine",
871 .selection_base = 14,
872 .selection_extent = 14,
879 g_assert_not_reached();
890 "preedit-changed",
nullptr);
892 "Flutter engine",
nullptr);
894 "preedit-end",
nullptr);
895 EXPECT_EQ(call_count, 3);
902 .enable_delta_model =
true,
907 messenger,
"flutter/textinput",
908 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
910 int* call_count =
static_cast<int*
>(
user_data);
912 EXPECT_STREQ(
name,
"TextInputClient.updateEditingStateWithDeltas");
914 switch (*call_count) {
928 .selection_extent = 1,
929 .composing_base = -1,
930 .composing_extent = -1,
949 .selection_extent = 2,
950 .composing_base = -1,
951 .composing_extent = -1,
970 .selection_extent = 3,
971 .composing_base = -1,
972 .composing_extent = -1,
991 .selection_extent = 4,
992 .composing_base = -1,
993 .composing_extent = -1,
1011 .selection_base = 5,
1012 .selection_extent = 5,
1013 .composing_base = -1,
1014 .composing_extent = -1,
1028 .old_text =
"Flutt",
1032 .selection_base = 6,
1033 .selection_extent = 6,
1034 .composing_base = -1,
1035 .composing_extent = -1,
1049 .old_text =
"Flutte",
1053 .selection_base = 7,
1054 .selection_extent = 7,
1055 .composing_base = -1,
1056 .composing_extent = -1,
1063 g_assert_not_reached();
1087 EXPECT_EQ(call_count, 7);
1091 EXPECT_CALL(mock_gtk,
1092 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1093 GTK_INPUT_PURPOSE_NUMBER));
1094 EXPECT_CALL(mock_gtk,
1095 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1096 GTK_INPUT_HINT_NONE));
1100 .input_type =
"TextInputType.number",
1105 EXPECT_CALL(mock_gtk,
1106 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1107 GTK_INPUT_PURPOSE_PHONE));
1108 EXPECT_CALL(mock_gtk,
1109 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1110 GTK_INPUT_HINT_NONE));
1114 .input_type =
"TextInputType.phone",
1119 EXPECT_CALL(mock_gtk,
1120 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1121 GTK_INPUT_PURPOSE_EMAIL));
1122 EXPECT_CALL(mock_gtk,
1123 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1124 GTK_INPUT_HINT_NONE));
1128 .input_type =
"TextInputType.emailAddress",
1133 EXPECT_CALL(mock_gtk,
1134 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1135 GTK_INPUT_PURPOSE_URL));
1136 EXPECT_CALL(mock_gtk,
1137 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1138 GTK_INPUT_HINT_NONE));
1142 .input_type =
"TextInputType.url",
1147 EXPECT_CALL(mock_gtk,
1148 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1149 GTK_INPUT_PURPOSE_PASSWORD));
1150 EXPECT_CALL(mock_gtk,
1151 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1152 GTK_INPUT_HINT_NONE));
1156 .input_type =
"TextInputType.visiblePassword",
1161 EXPECT_CALL(mock_gtk,
1162 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1163 GTK_INPUT_PURPOSE_NAME));
1164 EXPECT_CALL(mock_gtk,
1165 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1166 GTK_INPUT_HINT_UPPERCASE_WORDS));
1170 .input_type =
"TextInputType.name",
1175 EXPECT_CALL(mock_gtk,
1176 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1177 GTK_INPUT_PURPOSE_FREE_FORM));
1178 EXPECT_CALL(mock_gtk,
1179 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1180 GTK_INPUT_HINT_UPPERCASE_WORDS));
1184 .input_type =
"TextInputType.address",
1189 EXPECT_CALL(mock_gtk,
1190 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1191 GTK_INPUT_PURPOSE_FREE_FORM));
1194 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1195 static_cast<gint
>(GTK_INPUT_HINT_SPELLCHECK |
1196 GTK_INPUT_HINT_UPPERCASE_SENTENCES)));
1200 .input_type =
"TextInputType.multiline",
1205 EXPECT_CALL(mock_gtk,
1206 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1207 GTK_INPUT_PURPOSE_FREE_FORM));
1208 EXPECT_CALL(mock_gtk,
1209 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1210 GTK_INPUT_HINT_LOWERCASE));
1214 .input_type =
"TextInputType.webSearch",
1219 EXPECT_CALL(mock_gtk,
1220 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1221 GTK_INPUT_PURPOSE_FREE_FORM));
1224 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1225 static_cast<gint
>(GTK_INPUT_HINT_SPELLCHECK |
1226 GTK_INPUT_HINT_UPPERCASE_SENTENCES)));
1230 .input_type =
"TextInputType.twitter",
1235 EXPECT_CALL(mock_gtk,
1236 g_object_set(::testing::_, ::testing::StrEq(
"input-purpose"),
1237 GTK_INPUT_PURPOSE_FREE_FORM));
1238 EXPECT_CALL(mock_gtk,
1239 g_object_set(::testing::_, ::testing::StrEq(
"input-hints"),
1240 GTK_INPUT_HINT_NONE));
1244 .input_type =
"TextInputType.text",
1251 .input_action =
"TextInputAction.none",
1255 gboolean called = FALSE;
1264 messenger,
"flutter/textinput",
"TextInput.updateConfig", config,
1265 [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
1267 gboolean* called =
static_cast<gboolean*
>(
user_data);
1270 EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
1274 FL_METHOD_SUCCESS_RESPONSE(response)),
1278 EXPECT_TRUE(called);
1282 .selection_base = 7,
1283 .selection_extent = 7,
1289 messenger,
"flutter/textinput",
1290 [](FlMockBinaryMessenger* messenger, GTask* task,
const gchar*
name,
1292 int* call_count =
static_cast<int*
>(
user_data);
1294 EXPECT_STREQ(
name,
"TextInputClient.performAction");
1307 EXPECT_EQ(call_count, 1);
FlMockBinaryMessenger * messenger
::testing::NiceMock< flutter::testing::MockGtk > mock_gtk
~FlTextInputHandlerTest()
FlTextInputHandler * handler
g_autoptr(FlEngine) engine
void fl_binary_messenger_shutdown(FlBinaryMessenger *self)
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)
void fl_text_input_handler_set_widget(FlTextInputHandler *self, GtkWidget *widget)
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)
static void set_editing_state(FlMockBinaryMessenger *messenger, EditingState state)
TEST_F(FlTextInputHandlerTest, MessageHandler)
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)
GtkWidget * gtk_window_new(GtkWindowType type)
void g_object_set(gpointer object, const gchar *first_property_name,...)
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)