10 #include "flutter/shell/platform/linux/testing/fl_mock_binary_messenger.h"
11 #include "flutter/shell/platform/linux/testing/fl_test.h"
12 #include "flutter/shell/platform/linux/testing/mock_im_context.h"
13 #include "flutter/testing/testing.h"
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;
103 fl_mock_binary_messenger_invoke_json_method(
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;
125 fl_mock_binary_messenger_invoke_json_method(
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;
154 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
155 ::testing::NiceMock<flutter::testing::MockIMContext> context;
157 g_autoptr(FlTextInputHandler) handler =
159 EXPECT_NE(handler,
nullptr);
162 fl_mock_binary_messenger_has_handler(messenger,
"flutter/textinput"));
167 TEST(FlTextInputHandlerTest, SetClient) {
168 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
169 ::testing::NiceMock<flutter::testing::MockIMContext> context;
171 g_autoptr(FlTextInputHandler) handler =
173 EXPECT_NE(handler,
nullptr);
180 TEST(FlTextInputHandlerTest, Show) {
181 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
182 ::testing::NiceMock<flutter::testing::MockIMContext> context;
184 g_autoptr(FlTextInputHandler) handler =
186 EXPECT_NE(handler,
nullptr);
188 EXPECT_CALL(context, gtk_im_context_focus_in);
190 gboolean called = FALSE;
191 fl_mock_binary_messenger_invoke_json_method(
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)),
211 TEST(FlTextInputHandlerTest, Hide) {
212 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
213 ::testing::NiceMock<flutter::testing::MockIMContext> context;
215 g_autoptr(FlTextInputHandler) handler =
217 EXPECT_NE(handler,
nullptr);
219 EXPECT_CALL(context, gtk_im_context_focus_out);
221 gboolean called = FALSE;
222 fl_mock_binary_messenger_invoke_json_method(
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)),
242 TEST(FlTextInputHandlerTest, ClearClient) {
243 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
244 ::testing::NiceMock<flutter::testing::MockIMContext> context;
246 g_autoptr(FlTextInputHandler) handler =
248 EXPECT_NE(handler,
nullptr);
250 gboolean called = FALSE;
251 fl_mock_binary_messenger_invoke_json_method(
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)),
271 TEST(FlTextInputHandlerTest, PerformAction) {
272 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
273 ::testing::NiceMock<flutter::testing::MockIMContext> context;
275 g_autoptr(FlTextInputHandler) handler =
277 EXPECT_NE(handler,
nullptr);
281 .input_type =
"TextInputType.multiline",
282 .input_action =
"TextInputAction.newline",
287 .selection_extent = 7,
292 fl_mock_binary_messenger_set_json_method_channel(
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);
331 TEST(FlTextInputHandlerTest, MultilineWithSendAction) {
332 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
333 ::testing::NiceMock<flutter::testing::MockIMContext> context;
335 g_autoptr(FlTextInputHandler) handler =
337 EXPECT_NE(handler,
nullptr);
341 .input_type =
"TextInputType.multiline",
342 .input_action =
"TextInputAction.send",
347 .selection_extent = 7,
356 fl_mock_binary_messenger_set_json_method_channel(
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");
363 g_autoptr(
FlValue) expected_args =
nullptr;
364 switch (*call_count) {
373 g_assert_not_reached();
384 EXPECT_EQ(call_count, 1);
389 TEST(FlTextInputHandlerTest, MoveCursor) {
390 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
391 ::testing::NiceMock<flutter::testing::MockIMContext> context;
393 g_autoptr(FlTextInputHandler) handler =
395 EXPECT_NE(handler,
nullptr);
401 .selection_extent = 4,
405 fl_mock_binary_messenger_set_json_method_channel(
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");
412 g_autoptr(
FlValue) expected_args =
nullptr;
413 switch (*call_count) {
421 .selection_extent = 0,
432 .selection_extent = 7,
437 g_assert_not_reached();
449 EXPECT_EQ(call_count, 2);
454 TEST(FlTextInputHandlerTest, Select) {
455 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
456 ::testing::NiceMock<flutter::testing::MockIMContext> context;
458 g_autoptr(FlTextInputHandler) handler =
460 EXPECT_NE(handler,
nullptr);
466 .selection_extent = 4,
470 fl_mock_binary_messenger_set_json_method_channel(
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");
477 g_autoptr(
FlValue) expected_args =
nullptr;
478 switch (*call_count) {
486 .selection_extent = 7,
497 .selection_extent = 0,
502 g_assert_not_reached();
514 EXPECT_EQ(call_count, 2);
519 TEST(FlTextInputHandlerTest, Composing) {
520 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
521 ::testing::NiceMock<flutter::testing::MockIMContext> context;
523 g_autoptr(FlTextInputHandler) handler =
525 EXPECT_NE(handler,
nullptr);
528 EXPECT_CALL(context, gtk_im_context_get_preedit_string(
529 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
530 ::testing::A<gint*>()))
532 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter")),
533 ::testing::SetArgPointee<3>(0)));
536 fl_mock_binary_messenger_set_json_method_channel(
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");
543 g_autoptr(
FlValue) expected_args =
nullptr;
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);
603 TEST(FlTextInputHandlerTest, SurroundingText) {
604 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
605 ::testing::NiceMock<flutter::testing::MockIMContext> context;
607 g_autoptr(FlTextInputHandler) handler =
609 EXPECT_NE(handler,
nullptr);
615 .selection_extent = 3,
619 EXPECT_CALL(context, gtk_im_context_set_surrounding(
620 ::testing::_, ::testing::StrEq(
"Flutter"), -1, 3));
622 gboolean retrieved =
false;
624 "retrieve-surrounding", &retrieved,
nullptr);
625 EXPECT_TRUE(retrieved);
628 fl_mock_binary_messenger_set_json_method_channel(
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");
635 g_autoptr(
FlValue) expected_args =
nullptr;
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);
668 TEST(FlTextInputHandlerTest, SetMarkedTextRect) {
669 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
670 ::testing::NiceMock<flutter::testing::MockIMContext> context;
672 g_autoptr(FlTextInputHandler) handler =
674 EXPECT_NE(handler,
nullptr);
677 "preedit-start",
nullptr);
703 gboolean called = FALSE;
704 fl_mock_binary_messenger_invoke_json_method(
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)),
722 EXPECT_CALL(context, gtk_widget_translate_coordinates(
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)));
729 EXPECT_CALL(context, gtk_im_context_set_cursor_location(
731 ::testing::Pointee(::testing::AllOf(
732 ::testing::Field(&GdkRectangle::x, 123),
733 ::testing::Field(&GdkRectangle::y, 456),
745 fl_mock_binary_messenger_invoke_json_method(
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)),
765 TEST(FlTextInputHandlerTest, TextInputTypeNone) {
766 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
767 ::testing::NiceMock<flutter::testing::MockIMContext> context;
769 g_autoptr(FlTextInputHandler) handler =
771 EXPECT_NE(handler,
nullptr);
775 .input_type =
"TextInputType.none",
778 EXPECT_CALL(context, gtk_im_context_focus_in).Times(0);
779 EXPECT_CALL(context, gtk_im_context_focus_out);
781 gboolean called = FALSE;
782 fl_mock_binary_messenger_invoke_json_method(
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)),
802 TEST(FlTextInputHandlerTest, TextEditingDelta) {
803 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
804 ::testing::NiceMock<flutter::testing::MockIMContext> context;
806 g_autoptr(FlTextInputHandler) handler =
808 EXPECT_NE(handler,
nullptr);
812 .enable_delta_model =
true,
817 .selection_extent = 7,
822 fl_mock_binary_messenger_set_json_method_channel(
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");
829 g_autoptr(
FlValue) expected_args =
nullptr;
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);
866 TEST(FlTextInputHandlerTest, ComposingDelta) {
867 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
868 ::testing::NiceMock<flutter::testing::MockIMContext> context;
870 g_autoptr(FlTextInputHandler) handler =
872 EXPECT_NE(handler,
nullptr);
877 .enable_delta_model =
true,
881 "preedit-start",
nullptr);
884 EXPECT_CALL(context, gtk_im_context_get_preedit_string(
885 ::testing::_, ::testing::A<gchar**>(), ::testing::_,
886 ::testing::A<gint*>()))
888 ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup(
"Flutter ")),
889 ::testing::SetArgPointee<3>(8)));
892 fl_mock_binary_messenger_set_json_method_channel(
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");
899 g_autoptr(
FlValue) expected_args =
nullptr;
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);
980 TEST(FlTextInputHandlerTest, NonComposingDelta) {
981 g_autoptr(FlMockBinaryMessenger) messenger = fl_mock_binary_messenger_new();
982 ::testing::NiceMock<flutter::testing::MockIMContext> context;
984 g_autoptr(FlTextInputHandler) handler =
986 EXPECT_NE(handler,
nullptr);
991 .enable_delta_model =
true,
995 fl_mock_binary_messenger_set_json_method_channel(
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");
1002 g_autoptr(
FlValue) expected_args =
nullptr;
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);