Flutter Linux Embedder
fl_text_input_handler_test.cc File Reference
#include <utility>
#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_text_input_handler.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_gtk.h"
#include "flutter/testing/testing.h"
#include "flutter/shell/platform/linux/testing/linux_test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Classes

struct  InputConfig
 
struct  EditingState
 
struct  EditingDelta
 
class  FlTextInputHandlerTest
 

Functions

static FlValuebuild_map (std::map< const gchar *, FlValue * > args)
 
static FlValuebuild_list (std::vector< FlValue * > args)
 
static FlValuebuild_input_config (InputConfig config)
 
static FlValuebuild_editing_state (EditingState state)
 
static FlValuebuild_editing_delta (EditingDelta delta)
 
static void set_client (FlMockBinaryMessenger *messenger, InputConfig config)
 
static void set_editing_state (FlMockBinaryMessenger *messenger, EditingState state)
 
static void send_key_event (FlTextInputHandler *handler, gint keyval, gint state=0)
 
 TEST_F (FlTextInputHandlerTest, MessageHandler)
 
 TEST_F (FlTextInputHandlerTest, SetClient)
 
 TEST_F (FlTextInputHandlerTest, Show)
 
 TEST_F (FlTextInputHandlerTest, Hide)
 
 TEST_F (FlTextInputHandlerTest, ClearClient)
 
 TEST_F (FlTextInputHandlerTest, PerformAction)
 
 TEST_F (FlTextInputHandlerTest, MultilineWithSendAction)
 
 TEST_F (FlTextInputHandlerTest, MoveCursor)
 
 TEST_F (FlTextInputHandlerTest, Select)
 
 TEST_F (FlTextInputHandlerTest, Composing)
 
 TEST_F (FlTextInputHandlerTest, SurroundingText)
 
 TEST_F (FlTextInputHandlerTest, SetMarkedTextRect)
 
 TEST_F (FlTextInputHandlerTest, SetMarkedTextRectWithoutWidget)
 
 TEST_F (FlTextInputHandlerTest, TextInputTypeNone)
 
 TEST_F (FlTextInputHandlerTest, TextEditingDelta)
 
 TEST_F (FlTextInputHandlerTest, ComposingDelta)
 
 TEST_F (FlTextInputHandlerTest, NonComposingDelta)
 
 TEST_F (FlTextInputHandlerTest, InputPurposeNumber)
 
 TEST_F (FlTextInputHandlerTest, InputPurposePhone)
 
 TEST_F (FlTextInputHandlerTest, InputPurposeEmail)
 
 TEST_F (FlTextInputHandlerTest, InputPurposeUrl)
 
 TEST_F (FlTextInputHandlerTest, InputPurposePassword)
 
 TEST_F (FlTextInputHandlerTest, InputPurposeName)
 
 TEST_F (FlTextInputHandlerTest, InputHintsAddress)
 
 TEST_F (FlTextInputHandlerTest, InputHintsMultiline)
 
 TEST_F (FlTextInputHandlerTest, InputHintsWebSearch)
 
 TEST_F (FlTextInputHandlerTest, InputHintsTwitter)
 
 TEST_F (FlTextInputHandlerTest, DefaultInputPurposeAndHints)
 
 TEST_F (FlTextInputHandlerTest, UpdateConfig)
 

Function Documentation

◆ build_editing_delta()

static FlValue* build_editing_delta ( EditingDelta  delta)
static

Definition at line 86 of file fl_text_input_handler_test.cc.

86  {
87  return build_map({
88  {"oldText", fl_value_new_string(delta.old_text)},
89  {"deltaText", fl_value_new_string(delta.delta_text)},
90  {"deltaStart", fl_value_new_int(delta.delta_start)},
91  {"deltaEnd", fl_value_new_int(delta.delta_end)},
92  {"selectionBase", fl_value_new_int(delta.selection_base)},
93  {"selectionExtent", fl_value_new_int(delta.selection_extent)},
94  {"selectionAffinity", fl_value_new_string("TextAffinity.downstream")},
95  {"selectionIsDirectional", fl_value_new_bool(false)},
96  {"composingBase", fl_value_new_int(delta.composing_base)},
97  {"composingExtent", fl_value_new_int(delta.composing_extent)},
98  });
99 }
static FlValue * build_map(std::map< const gchar *, FlValue * > args)
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262

References build_map(), EditingDelta::composing_base, EditingDelta::composing_extent, EditingDelta::delta_end, EditingDelta::delta_start, EditingDelta::delta_text, fl_value_new_bool(), fl_value_new_int(), fl_value_new_string(), EditingDelta::old_text, EditingDelta::selection_base, and EditingDelta::selection_extent.

Referenced by TEST_F().

◆ build_editing_state()

static FlValue* build_editing_state ( EditingState  state)
static

Definition at line 63 of file fl_text_input_handler_test.cc.

63  {
64  return build_map({
65  {"text", fl_value_new_string(state.text)},
66  {"selectionBase", fl_value_new_int(state.selection_base)},
67  {"selectionExtent", fl_value_new_int(state.selection_extent)},
68  {"selectionAffinity", fl_value_new_string("TextAffinity.downstream")},
69  {"selectionIsDirectional", fl_value_new_bool(false)},
70  {"composingBase", fl_value_new_int(state.composing_base)},
71  {"composingExtent", fl_value_new_int(state.composing_extent)},
72  });
73 }

References build_map(), EditingState::composing_base, EditingState::composing_extent, fl_value_new_bool(), fl_value_new_int(), fl_value_new_string(), EditingState::selection_base, EditingState::selection_extent, and EditingState::text.

Referenced by set_editing_state(), and TEST_F().

◆ build_input_config()

static FlValue* build_input_config ( InputConfig  config)
static

Definition at line 42 of file fl_text_input_handler_test.cc.

42  {
43  return build_list({
45  build_map({
46  {"inputAction", fl_value_new_string(config.input_action)},
47  {"inputType", build_map({
48  {"name", fl_value_new_string(config.input_type)},
49  })},
50  {"enableDeltaModel", fl_value_new_bool(config.enable_delta_model)},
51  }),
52  });
53 }
static FlValue * build_list(std::vector< FlValue * > args)
const gchar * input_action

References build_list(), build_map(), InputConfig::client_id, InputConfig::enable_delta_model, fl_value_new_bool(), fl_value_new_int(), fl_value_new_string(), InputConfig::input_action, and InputConfig::input_type.

Referenced by set_client().

◆ build_list()

static FlValue* build_list ( std::vector< FlValue * >  args)
static

Definition at line 27 of file fl_text_input_handler_test.cc.

27  {
29  for (auto it = args.begin(); it != args.end(); ++it) {
31  }
32  return value;
33 }
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:349
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42

References args, fl_value_append_take(), fl_value_new_list(), and value.

Referenced by build_input_config(), and TEST_F().

◆ build_map()

static FlValue* build_map ( std::map< const gchar *, FlValue * >  args)
static

Definition at line 19 of file fl_text_input_handler_test.cc.

19  {
21  for (auto it = args.begin(); it != args.end(); ++it) {
22  fl_value_set_string_take(value, it->first, it->second);
23  }
24  return value;
25 }
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366

References args, fl_value_new_map(), fl_value_set_string_take(), and value.

Referenced by build_editing_delta(), build_editing_state(), build_input_config(), and TEST_F().

◆ send_key_event()

static void send_key_event ( FlTextInputHandler *  handler,
gint  keyval,
gint  state = 0 
)
static

Definition at line 144 of file fl_text_input_handler_test.cc.

146  {
147  GdkEvent* gdk_event = gdk_event_new(GDK_KEY_PRESS);
148  gdk_event->key.keyval = keyval;
149  gdk_event->key.state = state;
150  g_autoptr(FlKeyEvent) key_event = fl_key_event_new_from_gdk_event(gdk_event);
151  fl_text_input_handler_filter_keypress(handler, key_event);
152 }
g_autoptr(FlEngine) engine
FlKeyEvent * fl_key_event_new_from_gdk_event(GdkEvent *event)
Definition: fl_key_event.cc:53
gboolean fl_text_input_handler_filter_keypress(FlTextInputHandler *self, FlKeyEvent *event)

References fl_key_event_new_from_gdk_event(), fl_text_input_handler_filter_keypress(), and g_autoptr().

Referenced by TEST_F().

◆ set_client()

static void set_client ( FlMockBinaryMessenger *  messenger,
InputConfig  config 
)
static

Definition at line 101 of file fl_text_input_handler_test.cc.

101  {
102  gboolean called = FALSE;
104  fl_mock_binary_messenger_invoke_json_method(
105  messenger, "flutter/textinput", "TextInput.setClient", args,
106  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
107  gpointer user_data) {
108  gboolean* called = static_cast<gboolean*>(user_data);
109  *called = TRUE;
110 
111  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
112 
113  g_autoptr(FlValue) expected_result = fl_value_new_null();
115  FL_METHOD_SUCCESS_RESPONSE(response)),
116  expected_result));
117  },
118  &called);
119  EXPECT_TRUE(called);
120 }
const char FlTextDirection FlAssertiveness gpointer user_data
return TRUE
G_MODULE_EXPORT FlValue * fl_method_success_response_get_result(FlMethodSuccessResponse *self)
static FlValue * build_input_config(InputConfig config)
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471

References args, build_input_config(), fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), TRUE, and user_data.

Referenced by TEST_F().

◆ set_editing_state()

static void set_editing_state ( FlMockBinaryMessenger *  messenger,
EditingState  state 
)
static

Definition at line 122 of file fl_text_input_handler_test.cc.

123  {
124  gboolean called = FALSE;
126  fl_mock_binary_messenger_invoke_json_method(
127  messenger, "flutter/textinput", "TextInput.setEditingState", args,
128  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
129  gpointer user_data) {
130  gboolean* called = static_cast<gboolean*>(user_data);
131  *called = TRUE;
132 
133  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
134 
135  g_autoptr(FlValue) expected_result = fl_value_new_null();
137  FL_METHOD_SUCCESS_RESPONSE(response)),
138  expected_result));
139  },
140  &called);
141  EXPECT_TRUE(called);
142 }
static FlValue * build_editing_state(EditingState state)

References args, build_editing_state(), fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), TRUE, and user_data.

Referenced by TEST_F().

◆ TEST_F() [1/29]

TEST_F ( FlTextInputHandlerTest  ,
ClearClient   
)

Definition at line 225 of file fl_text_input_handler_test.cc.

225  {
226  gboolean called = FALSE;
227  fl_mock_binary_messenger_invoke_json_method(
228  messenger, "flutter/textinput", "TextInput.clearClient", nullptr,
229  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
230  gpointer user_data) {
231  gboolean* called = static_cast<gboolean*>(user_data);
232  *called = TRUE;
233 
234  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
235 
236  g_autoptr(FlValue) expected_result = fl_value_new_null();
238  FL_METHOD_SUCCESS_RESPONSE(response)),
239  expected_result));
240  },
241  &called);
242  EXPECT_TRUE(called);
243 }

References fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), TRUE, and user_data.

◆ TEST_F() [2/29]

TEST_F ( FlTextInputHandlerTest  ,
Composing   
)

Definition at line 457 of file fl_text_input_handler_test.cc.

457  {
458  // update
459  EXPECT_CALL(mock_gtk, gtk_im_context_get_preedit_string(
460  ::testing::_, ::testing::A<gchar**>(), ::testing::_,
461  ::testing::A<gint*>()))
462  .WillOnce(
463  ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup("Flutter")),
464  ::testing::SetArgPointee<3>(0)));
465 
466  int call_count = 0;
467  fl_mock_binary_messenger_set_json_method_channel(
468  messenger, "flutter/textinput",
469  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
470  FlValue* args, gpointer user_data) {
471  int* call_count = static_cast<int*>(user_data);
472 
473  EXPECT_STREQ(name, "TextInputClient.updateEditingState");
474  g_autoptr(FlValue) expected_args = nullptr;
475  switch (*call_count) {
476  case 0:
477  expected_args = build_list({
478  fl_value_new_int(-1), // client_id
480  .text = "Flutter",
481  .selection_base = 0,
482  .selection_extent = 0,
483  .composing_base = 0,
484  .composing_extent = 7,
485  }),
486  });
487  break;
488  case 1:
489  // commit
490  expected_args = build_list({
491  fl_value_new_int(-1), // client_id
493  .text = "engine",
494  .selection_base = 6,
495  .selection_extent = 6,
496  }),
497  });
498  break;
499  case 2:
500  // end
501  expected_args = build_list({
502  fl_value_new_int(-1), // client_id
504  .text = "engine",
505  .selection_base = 6,
506  .selection_extent = 6,
507  }),
508  });
509  break;
510  default:
511  g_assert_not_reached();
512  break;
513  }
514  EXPECT_TRUE(fl_value_equal(args, expected_args));
515  (*call_count)++;
516 
517  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
518  },
519  &call_count);
520 
521  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
522  "preedit-start", nullptr);
523  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
524  "preedit-changed", nullptr);
525  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
526  "engine", nullptr);
527  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
528  "preedit-end", nullptr);
529  EXPECT_EQ(call_count, 3);
530 }
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
GtkIMContext * fl_text_input_handler_get_im_context(FlTextInputHandler *self)

References args, build_editing_state(), build_list(), fl_method_success_response_new(), fl_text_input_handler_get_im_context(), fl_value_equal(), fl_value_new_int(), g_autoptr(), and user_data.

◆ TEST_F() [3/29]

TEST_F ( FlTextInputHandlerTest  ,
ComposingDelta   
)

Definition at line 793 of file fl_text_input_handler_test.cc.

793  {
794  // set config
795  set_client(messenger, {
796  .client_id = 1,
797  .enable_delta_model = true,
798  });
799 
800  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
801  "preedit-start", nullptr);
802 
803  // update
804  EXPECT_CALL(mock_gtk, gtk_im_context_get_preedit_string(
805  ::testing::_, ::testing::A<gchar**>(), ::testing::_,
806  ::testing::A<gint*>()))
807  .WillOnce(
808  ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup("Flutter ")),
809  ::testing::SetArgPointee<3>(8)));
810 
811  int call_count = 0;
812  fl_mock_binary_messenger_set_json_method_channel(
813  messenger, "flutter/textinput",
814  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
815  FlValue* args, gpointer user_data) {
816  int* call_count = static_cast<int*>(user_data);
817 
818  EXPECT_STREQ(name, "TextInputClient.updateEditingStateWithDeltas");
819  g_autoptr(FlValue) expected_args = nullptr;
820  switch (*call_count) {
821  case 0:
822  expected_args = build_list({
823  fl_value_new_int(1), // client_id
824  build_map({{
825  "deltas",
826  build_list({
828  .old_text = "",
829  .delta_text = "Flutter ",
830  .delta_start = 0,
831  .delta_end = 0,
832  .selection_base = 8,
833  .selection_extent = 8,
834  .composing_base = 0,
835  .composing_extent = 8,
836  }),
837  }),
838  }}),
839  });
840  break;
841  case 1:
842  // commit
843  expected_args = build_list({
844  fl_value_new_int(1), // client_id
845  build_map({{
846  "deltas",
847  build_list({
849  .old_text = "Flutter ",
850  .delta_text = "Flutter engine",
851  .delta_start = 0,
852  .delta_end = 8,
853  .selection_base = 14,
854  .selection_extent = 14,
855  .composing_base = -1,
856  .composing_extent = -1,
857  }),
858  }),
859  }}),
860  });
861  break;
862  case 2:
863  // end
864  expected_args = build_list({
865  fl_value_new_int(1), // client_id
866  build_map({{
867  "deltas",
868  build_list({
870  .old_text = "Flutter engine",
871  .selection_base = 14,
872  .selection_extent = 14,
873  }),
874  }),
875  }}),
876  });
877  break;
878  default:
879  g_assert_not_reached();
880  break;
881  }
882  EXPECT_TRUE(fl_value_equal(args, expected_args));
883  (*call_count)++;
884 
885  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
886  },
887  &call_count);
888 
889  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
890  "preedit-changed", nullptr);
891  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
892  "Flutter engine", nullptr);
893  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
894  "preedit-end", nullptr);
895  EXPECT_EQ(call_count, 3);
896 }
static void set_client(FlMockBinaryMessenger *messenger, InputConfig config)
static FlValue * build_editing_delta(EditingDelta delta)

References args, build_editing_delta(), build_list(), build_map(), fl_method_success_response_new(), fl_text_input_handler_get_im_context(), fl_value_equal(), fl_value_new_int(), g_autoptr(), set_client(), and user_data.

◆ TEST_F() [4/29]

TEST_F ( FlTextInputHandlerTest  ,
DefaultInputPurposeAndHints   
)

Definition at line 1234 of file fl_text_input_handler_test.cc.

1234  {
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));
1241 
1242  set_client(messenger, {
1243  .client_id = 1,
1244  .input_type = "TextInputType.text",
1245  });
1246 }

References set_client().

◆ TEST_F() [5/29]

TEST_F ( FlTextInputHandlerTest  ,
Hide   
)

Definition at line 203 of file fl_text_input_handler_test.cc.

203  {
204  EXPECT_CALL(mock_gtk, gtk_im_context_focus_out);
205 
206  gboolean called = FALSE;
207  fl_mock_binary_messenger_invoke_json_method(
208  messenger, "flutter/textinput", "TextInput.hide", nullptr,
209  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
210  gpointer user_data) {
211  gboolean* called = static_cast<gboolean*>(user_data);
212  *called = TRUE;
213 
214  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
215 
216  g_autoptr(FlValue) expected_result = fl_value_new_null();
218  FL_METHOD_SUCCESS_RESPONSE(response)),
219  expected_result));
220  },
221  &called);
222  EXPECT_TRUE(called);
223 }

References fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), TRUE, and user_data.

◆ TEST_F() [6/29]

TEST_F ( FlTextInputHandlerTest  ,
InputHintsAddress   
)

Definition at line 1174 of file fl_text_input_handler_test.cc.

1174  {
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));
1181 
1182  set_client(messenger, {
1183  .client_id = 1,
1184  .input_type = "TextInputType.address",
1185  });
1186 }

References set_client().

◆ TEST_F() [7/29]

TEST_F ( FlTextInputHandlerTest  ,
InputHintsMultiline   
)

Definition at line 1188 of file fl_text_input_handler_test.cc.

1188  {
1189  EXPECT_CALL(mock_gtk,
1190  g_object_set(::testing::_, ::testing::StrEq("input-purpose"),
1191  GTK_INPUT_PURPOSE_FREE_FORM));
1192  EXPECT_CALL(
1193  mock_gtk,
1194  g_object_set(::testing::_, ::testing::StrEq("input-hints"),
1195  static_cast<gint>(GTK_INPUT_HINT_SPELLCHECK |
1196  GTK_INPUT_HINT_UPPERCASE_SENTENCES)));
1197 
1198  set_client(messenger, {
1199  .client_id = 1,
1200  .input_type = "TextInputType.multiline",
1201  });
1202 }

References set_client().

◆ TEST_F() [8/29]

TEST_F ( FlTextInputHandlerTest  ,
InputHintsTwitter   
)

Definition at line 1218 of file fl_text_input_handler_test.cc.

1218  {
1219  EXPECT_CALL(mock_gtk,
1220  g_object_set(::testing::_, ::testing::StrEq("input-purpose"),
1221  GTK_INPUT_PURPOSE_FREE_FORM));
1222  EXPECT_CALL(
1223  mock_gtk,
1224  g_object_set(::testing::_, ::testing::StrEq("input-hints"),
1225  static_cast<gint>(GTK_INPUT_HINT_SPELLCHECK |
1226  GTK_INPUT_HINT_UPPERCASE_SENTENCES)));
1227 
1228  set_client(messenger, {
1229  .client_id = 1,
1230  .input_type = "TextInputType.twitter",
1231  });
1232 }

References set_client().

◆ TEST_F() [9/29]

TEST_F ( FlTextInputHandlerTest  ,
InputHintsWebSearch   
)

Definition at line 1204 of file fl_text_input_handler_test.cc.

1204  {
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));
1211 
1212  set_client(messenger, {
1213  .client_id = 1,
1214  .input_type = "TextInputType.webSearch",
1215  });
1216 }

References set_client().

◆ TEST_F() [10/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposeEmail   
)

Definition at line 1118 of file fl_text_input_handler_test.cc.

1118  {
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));
1125 
1126  set_client(messenger, {
1127  .client_id = 1,
1128  .input_type = "TextInputType.emailAddress",
1129  });
1130 }

References set_client().

◆ TEST_F() [11/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposeName   
)

Definition at line 1160 of file fl_text_input_handler_test.cc.

1160  {
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));
1167 
1168  set_client(messenger, {
1169  .client_id = 1,
1170  .input_type = "TextInputType.name",
1171  });
1172 }

References set_client().

◆ TEST_F() [12/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposeNumber   
)

Definition at line 1090 of file fl_text_input_handler_test.cc.

1090  {
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));
1097 
1098  set_client(messenger, {
1099  .client_id = 1,
1100  .input_type = "TextInputType.number",
1101  });
1102 }

References set_client().

◆ TEST_F() [13/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposePassword   
)

Definition at line 1146 of file fl_text_input_handler_test.cc.

1146  {
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));
1153 
1154  set_client(messenger, {
1155  .client_id = 1,
1156  .input_type = "TextInputType.visiblePassword",
1157  });
1158 }

References set_client().

◆ TEST_F() [14/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposePhone   
)

Definition at line 1104 of file fl_text_input_handler_test.cc.

1104  {
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));
1111 
1112  set_client(messenger, {
1113  .client_id = 1,
1114  .input_type = "TextInputType.phone",
1115  });
1116 }

References set_client().

◆ TEST_F() [15/29]

TEST_F ( FlTextInputHandlerTest  ,
InputPurposeUrl   
)

Definition at line 1132 of file fl_text_input_handler_test.cc.

1132  {
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));
1139 
1140  set_client(messenger, {
1141  .client_id = 1,
1142  .input_type = "TextInputType.url",
1143  });
1144 }

References set_client().

◆ TEST_F() [16/29]

TEST_F ( FlTextInputHandlerTest  ,
MessageHandler   
)

Definition at line 172 of file fl_text_input_handler_test.cc.

172  {
173  EXPECT_TRUE(
174  fl_mock_binary_messenger_has_handler(messenger, "flutter/textinput"));
175 }

◆ TEST_F() [17/29]

TEST_F ( FlTextInputHandlerTest  ,
MoveCursor   
)

Definition at line 345 of file fl_text_input_handler_test.cc.

345  {
346  set_client(messenger, {.client_id = 1});
347  set_editing_state(messenger, {
348  .text = "Flutter",
349  .selection_base = 4,
350  .selection_extent = 4,
351  });
352 
353  int call_count = 0;
354  fl_mock_binary_messenger_set_json_method_channel(
355  messenger, "flutter/textinput",
356  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
357  FlValue* args, gpointer user_data) {
358  int* call_count = static_cast<int*>(user_data);
359 
360  EXPECT_STREQ(name, "TextInputClient.updateEditingState");
361  g_autoptr(FlValue) expected_args = nullptr;
362  switch (*call_count) {
363  case 0:
364  // move cursor to beginning
365  expected_args = build_list({
366  fl_value_new_int(1), // client_id
368  .text = "Flutter",
369  .selection_base = 0,
370  .selection_extent = 0,
371  }),
372  });
373  break;
374  case 1:
375  // move cursor to end
376  expected_args = build_list({
377  fl_value_new_int(1), // client_id
379  .text = "Flutter",
380  .selection_base = 7,
381  .selection_extent = 7,
382  }),
383  });
384  break;
385  default:
386  g_assert_not_reached();
387  break;
388  }
389  EXPECT_TRUE(fl_value_equal(args, expected_args));
390  (*call_count)++;
391 
392  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
393  },
394  &call_count);
395 
396  send_key_event(handler, GDK_KEY_Home);
397  send_key_event(handler, GDK_KEY_End);
398  EXPECT_EQ(call_count, 2);
399 }
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
static void set_editing_state(FlMockBinaryMessenger *messenger, EditingState state)

References args, build_editing_state(), build_list(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_int(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [18/29]

TEST_F ( FlTextInputHandlerTest  ,
MultilineWithSendAction   
)

Definition at line 296 of file fl_text_input_handler_test.cc.

296  {
297  set_client(messenger, {
298  .client_id = 1,
299  .input_type = "TextInputType.multiline",
300  .input_action = "TextInputAction.send",
301  });
302  set_editing_state(messenger, {
303  .text = "Flutter",
304  .selection_base = 7,
305  .selection_extent = 7,
306  });
307 
308  // Because the input action is not set to TextInputAction.newline, the next
309  // expected call is "TextInputClient.performAction". If the input action was
310  // set to TextInputAction.newline the next call would be
311  // "TextInputClient.updateEditingState" (this case is tested in the test named
312  // 'PerformAction').
313  int call_count = 0;
314  fl_mock_binary_messenger_set_json_method_channel(
315  messenger, "flutter/textinput",
316  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
317  FlValue* args, gpointer user_data) {
318  int* call_count = static_cast<int*>(user_data);
319 
320  EXPECT_STREQ(name, "TextInputClient.performAction");
321  g_autoptr(FlValue) expected_args = nullptr;
322  switch (*call_count) {
323  case 0:
324  // Perform action.
325  expected_args = build_list({
326  fl_value_new_int(1), // client_id
327  fl_value_new_string("TextInputAction.send"),
328  });
329  break;
330  default:
331  g_assert_not_reached();
332  break;
333  }
334  EXPECT_TRUE(fl_value_equal(args, expected_args));
335  (*call_count)++;
336 
337  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
338  },
339  &call_count);
340 
341  send_key_event(handler, GDK_KEY_Return);
342  EXPECT_EQ(call_count, 1);
343 }

References args, build_list(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_int(), fl_value_new_string(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [19/29]

TEST_F ( FlTextInputHandlerTest  ,
NonComposingDelta   
)

Definition at line 898 of file fl_text_input_handler_test.cc.

898  {
899  // set config
900  set_client(messenger, {
901  .client_id = 1,
902  .enable_delta_model = true,
903  });
904 
905  int call_count = 0;
906  fl_mock_binary_messenger_set_json_method_channel(
907  messenger, "flutter/textinput",
908  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
909  FlValue* args, gpointer user_data) {
910  int* call_count = static_cast<int*>(user_data);
911 
912  EXPECT_STREQ(name, "TextInputClient.updateEditingStateWithDeltas");
913  g_autoptr(FlValue) expected_args = nullptr;
914  switch (*call_count) {
915  case 0:
916  // commit F
917  expected_args = build_list({
918  fl_value_new_int(1), // client_id
919  build_map({{
920  "deltas",
921  build_list({
923  .old_text = "",
924  .delta_text = "F",
925  .delta_start = 0,
926  .delta_end = 0,
927  .selection_base = 1,
928  .selection_extent = 1,
929  .composing_base = -1,
930  .composing_extent = -1,
931  }),
932  }),
933  }}),
934  });
935  break;
936  case 1:
937  // commit l
938  expected_args = build_list({
939  fl_value_new_int(1), // client_id
940  build_map({{
941  "deltas",
942  build_list({
944  .old_text = "F",
945  .delta_text = "l",
946  .delta_start = 1,
947  .delta_end = 1,
948  .selection_base = 2,
949  .selection_extent = 2,
950  .composing_base = -1,
951  .composing_extent = -1,
952  }),
953  }),
954  }}),
955  });
956  break;
957  case 2:
958  // commit u
959  expected_args = build_list({
960  fl_value_new_int(1), // client_id
961  build_map({{
962  "deltas",
963  build_list({
965  .old_text = "Fl",
966  .delta_text = "u",
967  .delta_start = 2,
968  .delta_end = 2,
969  .selection_base = 3,
970  .selection_extent = 3,
971  .composing_base = -1,
972  .composing_extent = -1,
973  }),
974  }),
975  }}),
976  });
977  break;
978  case 3:
979  // commit t
980  expected_args = build_list({
981  fl_value_new_int(1), // client_id
982  build_map({{
983  "deltas",
984  build_list({
986  .old_text = "Flu",
987  .delta_text = "t",
988  .delta_start = 3,
989  .delta_end = 3,
990  .selection_base = 4,
991  .selection_extent = 4,
992  .composing_base = -1,
993  .composing_extent = -1,
994  }),
995  }),
996  }}),
997  });
998  break;
999  case 4:
1000  // commit t again
1001  expected_args = build_list({
1002  fl_value_new_int(1), // client_id
1003  build_map({{
1004  "deltas",
1005  build_list({
1007  .old_text = "Flut",
1008  .delta_text = "t",
1009  .delta_start = 4,
1010  .delta_end = 4,
1011  .selection_base = 5,
1012  .selection_extent = 5,
1013  .composing_base = -1,
1014  .composing_extent = -1,
1015  }),
1016  }),
1017  }}),
1018  });
1019  break;
1020  case 5:
1021  // commit e
1022  expected_args = build_list({
1023  fl_value_new_int(1), // client_id
1024  build_map({{
1025  "deltas",
1026  build_list({
1028  .old_text = "Flutt",
1029  .delta_text = "e",
1030  .delta_start = 5,
1031  .delta_end = 5,
1032  .selection_base = 6,
1033  .selection_extent = 6,
1034  .composing_base = -1,
1035  .composing_extent = -1,
1036  }),
1037  }),
1038  }}),
1039  });
1040  break;
1041  case 6:
1042  // commit r
1043  expected_args = build_list({
1044  fl_value_new_int(1), // client_id
1045  build_map({{
1046  "deltas",
1047  build_list({
1049  .old_text = "Flutte",
1050  .delta_text = "r",
1051  .delta_start = 6,
1052  .delta_end = 6,
1053  .selection_base = 7,
1054  .selection_extent = 7,
1055  .composing_base = -1,
1056  .composing_extent = -1,
1057  }),
1058  }),
1059  }}),
1060  });
1061  break;
1062  default:
1063  g_assert_not_reached();
1064  break;
1065  }
1066  EXPECT_TRUE(fl_value_equal(args, expected_args));
1067  (*call_count)++;
1068 
1069  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
1070  },
1071  &call_count);
1072 
1073  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1074  "F", nullptr);
1075  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1076  "l", nullptr);
1077  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1078  "u", nullptr);
1079  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1080  "t", nullptr);
1081  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1082  "t", nullptr);
1083  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1084  "e", nullptr);
1085  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler), "commit",
1086  "r", nullptr);
1087  EXPECT_EQ(call_count, 7);
1088 }

References args, build_editing_delta(), build_list(), build_map(), fl_method_success_response_new(), fl_text_input_handler_get_im_context(), fl_value_equal(), fl_value_new_int(), g_autoptr(), set_client(), and user_data.

◆ TEST_F() [20/29]

TEST_F ( FlTextInputHandlerTest  ,
PerformAction   
)

Definition at line 245 of file fl_text_input_handler_test.cc.

245  {
246  set_client(messenger, {
247  .client_id = 1,
248  .input_type = "TextInputType.multiline",
249  .input_action = "TextInputAction.newline",
250  });
251  set_editing_state(messenger, {
252  .text = "Flutter",
253  .selection_base = 7,
254  .selection_extent = 7,
255  });
256 
257  // Client will update editing state and perform action
258  int call_count = 0;
259  fl_mock_binary_messenger_set_json_method_channel(
260  messenger, "flutter/textinput",
261  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
262  FlValue* args, gpointer user_data) {
263  int* call_count = static_cast<int*>(user_data);
264 
265  if (strcmp(name, "TextInputClient.updateEditingState") == 0) {
266  g_autoptr(FlValue) expected_args = build_list({
267  fl_value_new_int(1), // client_id
269  .text = "Flutter\n",
270  .selection_base = 8,
271  .selection_extent = 8,
272  }),
273  });
274  EXPECT_TRUE(fl_value_equal(args, expected_args));
275  EXPECT_EQ(*call_count, 0);
276  (*call_count)++;
277  } else if (strcmp(name, "TextInputClient.performAction") == 0) {
278  g_autoptr(FlValue) expected_args = build_list({
279  fl_value_new_int(1), // client_id
280  fl_value_new_string("TextInputAction.newline"),
281  });
282  EXPECT_TRUE(fl_value_equal(args, expected_args));
283  EXPECT_EQ(*call_count, 1);
284  (*call_count)++;
285  }
286 
287  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
288  },
289  &call_count);
290 
291  send_key_event(handler, GDK_KEY_Return);
292  EXPECT_EQ(call_count, 2);
293 }

References args, build_editing_state(), build_list(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_int(), fl_value_new_string(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [21/29]

TEST_F ( FlTextInputHandlerTest  ,
Select   
)

Definition at line 401 of file fl_text_input_handler_test.cc.

401  {
402  set_client(messenger, {.client_id = 1});
403  set_editing_state(messenger, {
404  .text = "Flutter",
405  .selection_base = 4,
406  .selection_extent = 4,
407  });
408 
409  int call_count = 0;
410  fl_mock_binary_messenger_set_json_method_channel(
411  messenger, "flutter/textinput",
412  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
413  FlValue* args, gpointer user_data) {
414  int* call_count = static_cast<int*>(user_data);
415 
416  EXPECT_STREQ(name, "TextInputClient.updateEditingState");
417  g_autoptr(FlValue) expected_args = nullptr;
418  switch (*call_count) {
419  case 0:
420  // select to end
421  expected_args = build_list({
422  fl_value_new_int(1), // client_id
424  .text = "Flutter",
425  .selection_base = 4,
426  .selection_extent = 7,
427  }),
428  });
429  break;
430  case 1:
431  // select to beginning
432  expected_args = build_list({
433  fl_value_new_int(1), // client_id
435  .text = "Flutter",
436  .selection_base = 4,
437  .selection_extent = 0,
438  }),
439  });
440  break;
441  default:
442  g_assert_not_reached();
443  break;
444  }
445  EXPECT_TRUE(fl_value_equal(args, expected_args));
446  (*call_count)++;
447 
448  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
449  },
450  &call_count);
451 
452  send_key_event(handler, GDK_KEY_End, GDK_SHIFT_MASK);
453  send_key_event(handler, GDK_KEY_Home, GDK_SHIFT_MASK);
454  EXPECT_EQ(call_count, 2);
455 }

References args, build_editing_state(), build_list(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_int(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [22/29]

TEST_F ( FlTextInputHandlerTest  ,
SetClient   
)

Definition at line 177 of file fl_text_input_handler_test.cc.

177  {
178  set_client(messenger, {.client_id = 1});
179 }

References set_client().

◆ TEST_F() [23/29]

TEST_F ( FlTextInputHandlerTest  ,
SetMarkedTextRect   
)

Definition at line 588 of file fl_text_input_handler_test.cc.

588  {
589  GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
590  g_object_ref_sink(window);
591  fl_text_input_handler_set_widget(handler, window);
592 
593  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
594  "preedit-start", nullptr);
595 
596  // set editable size and transform
597  g_autoptr(FlValue) size_and_transform = build_map({
598  {
599  "transform",
600  build_list({
610  fl_value_new_float(10),
611  fl_value_new_float(11),
612  fl_value_new_float(12),
613  fl_value_new_float(13),
614  fl_value_new_float(14),
615  fl_value_new_float(15),
616  fl_value_new_float(16),
617  }),
618  },
619  });
620  gboolean called = FALSE;
621  fl_mock_binary_messenger_invoke_json_method(
622  messenger, "flutter/textinput", "TextInput.setEditableSizeAndTransform",
623  size_and_transform,
624  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
625  gpointer user_data) {
626  gboolean* called = static_cast<gboolean*>(user_data);
627  *called = TRUE;
628 
629  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
630 
631  g_autoptr(FlValue) expected_result = fl_value_new_null();
633  FL_METHOD_SUCCESS_RESPONSE(response)),
634  expected_result));
635  },
636  &called);
637  EXPECT_TRUE(called);
638 
639  EXPECT_CALL(mock_gtk, gtk_widget_translate_coordinates(
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)));
645 
646  EXPECT_CALL(mock_gtk, gtk_im_context_set_cursor_location(
647  ::testing::_,
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)))));
653 
654  // set marked text rect
655  g_autoptr(FlValue) rect = build_map({
656  {"x", fl_value_new_float(1)},
657  {"y", fl_value_new_float(2)},
658  {"width", fl_value_new_float(3)},
659  {"height", fl_value_new_float(4)},
660  });
661  called = FALSE;
662  fl_mock_binary_messenger_invoke_json_method(
663  messenger, "flutter/textinput", "TextInput.setMarkedTextRect", rect,
664  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
665  gpointer user_data) {
666  gboolean* called = static_cast<gboolean*>(user_data);
667  *called = TRUE;
668 
669  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
670 
671  g_autoptr(FlValue) expected_result = fl_value_new_null();
673  FL_METHOD_SUCCESS_RESPONSE(response)),
674  expected_result));
675  },
676  &called);
677  EXPECT_TRUE(called);
678 
679  fl_text_input_handler_set_widget(handler, nullptr);
680  g_object_unref(window);
681 }
FlFramebuffer double double int int height
FlFramebuffer double x
FlFramebuffer double double int width
FlFramebuffer double double y
void fl_text_input_handler_set_widget(FlTextInputHandler *self, GtkWidget *widget)
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition: fl_value.cc:269

References build_list(), build_map(), fl_method_success_response_get_result(), fl_text_input_handler_get_im_context(), fl_text_input_handler_set_widget(), fl_value_equal(), fl_value_new_float(), fl_value_new_null(), g_autoptr(), height, TRUE, user_data, width, x, and y.

◆ TEST_F() [24/29]

TEST_F ( FlTextInputHandlerTest  ,
SetMarkedTextRectWithoutWidget   
)

Definition at line 685 of file fl_text_input_handler_test.cc.

685  {
686  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
687  "preedit-start", nullptr);
688 
689  EXPECT_CALL(mock_gtk, gtk_widget_translate_coordinates).Times(0);
690 
691  g_autoptr(FlValue) rect = build_map({
692  {"x", fl_value_new_float(1)},
693  {"y", fl_value_new_float(2)},
694  {"width", fl_value_new_float(3)},
695  {"height", fl_value_new_float(4)},
696  });
697  gboolean called = FALSE;
698  fl_mock_binary_messenger_invoke_json_method(
699  messenger, "flutter/textinput", "TextInput.setMarkedTextRect", rect,
700  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
701  gpointer user_data) {
702  gboolean* called = static_cast<gboolean*>(user_data);
703  *called = TRUE;
704  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
705  },
706  &called);
707  EXPECT_TRUE(called);
708 }

References build_map(), fl_text_input_handler_get_im_context(), fl_value_new_float(), g_autoptr(), TRUE, and user_data.

◆ TEST_F() [25/29]

TEST_F ( FlTextInputHandlerTest  ,
Show   
)

Definition at line 181 of file fl_text_input_handler_test.cc.

181  {
182  EXPECT_CALL(mock_gtk, gtk_im_context_focus_in);
183 
184  gboolean called = FALSE;
185  fl_mock_binary_messenger_invoke_json_method(
186  messenger, "flutter/textinput", "TextInput.show", nullptr,
187  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
188  gpointer user_data) {
189  gboolean* called = static_cast<gboolean*>(user_data);
190  *called = TRUE;
191 
192  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
193 
194  g_autoptr(FlValue) expected_result = fl_value_new_null();
196  FL_METHOD_SUCCESS_RESPONSE(response)),
197  expected_result));
198  },
199  &called);
200  EXPECT_TRUE(called);
201 }

References fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), TRUE, and user_data.

◆ TEST_F() [26/29]

TEST_F ( FlTextInputHandlerTest  ,
SurroundingText   
)

Definition at line 532 of file fl_text_input_handler_test.cc.

532  {
533  set_client(messenger, {.client_id = 1});
534  set_editing_state(messenger, {
535  .text = "Flutter",
536  .selection_base = 3,
537  .selection_extent = 3,
538  });
539 
540  // retrieve
541  EXPECT_CALL(mock_gtk, gtk_im_context_set_surrounding(
542  ::testing::_, ::testing::StrEq("Flutter"), -1, 3));
543 
544  gboolean retrieved = false;
545  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
546  "retrieve-surrounding", &retrieved, nullptr);
547  EXPECT_TRUE(retrieved);
548 
549  int call_count = 0;
550  fl_mock_binary_messenger_set_json_method_channel(
551  messenger, "flutter/textinput",
552  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
553  FlValue* args, gpointer user_data) {
554  int* call_count = static_cast<int*>(user_data);
555 
556  EXPECT_STREQ(name, "TextInputClient.updateEditingState");
557  g_autoptr(FlValue) expected_args = nullptr;
558  switch (*call_count) {
559  case 0:
560  // delete
561  expected_args = build_list({
562  fl_value_new_int(1), // client_id
564  .text = "Flutr",
565  .selection_base = 3,
566  .selection_extent = 3,
567  }),
568  });
569  break;
570  default:
571  g_assert_not_reached();
572  break;
573  }
574  EXPECT_TRUE(fl_value_equal(args, expected_args));
575  (*call_count)++;
576 
577  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
578  },
579  &call_count);
580 
581  gboolean deleted = false;
582  g_signal_emit_by_name(fl_text_input_handler_get_im_context(handler),
583  "delete-surrounding", 1, 2, &deleted, nullptr);
584  EXPECT_TRUE(deleted);
585  EXPECT_EQ(call_count, 1);
586 }

References args, build_editing_state(), build_list(), fl_method_success_response_new(), fl_text_input_handler_get_im_context(), fl_value_equal(), fl_value_new_int(), g_autoptr(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [27/29]

TEST_F ( FlTextInputHandlerTest  ,
TextEditingDelta   
)

Definition at line 738 of file fl_text_input_handler_test.cc.

738  {
739  set_client(messenger, {
740  .client_id = 1,
741  .enable_delta_model = true,
742  });
743  set_editing_state(messenger, {
744  .text = "Flutter",
745  .selection_base = 7,
746  .selection_extent = 7,
747  });
748 
749  // update editing state with deltas
750  int call_count = 0;
751  fl_mock_binary_messenger_set_json_method_channel(
752  messenger, "flutter/textinput",
753  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
754  FlValue* args, gpointer user_data) {
755  int* call_count = static_cast<int*>(user_data);
756 
757  EXPECT_STREQ(name, "TextInputClient.updateEditingStateWithDeltas");
758  g_autoptr(FlValue) expected_args = nullptr;
759  switch (*call_count) {
760  case 0:
761  expected_args = build_list({
762  fl_value_new_int(1), // client_id
763  build_map({{
764  "deltas",
765  build_list({
767  .old_text = "Flutter",
768  .delta_text = "Flutter",
769  .delta_start = 7,
770  .delta_end = 7,
771  .selection_base = 0,
772  .selection_extent = 0,
773  }),
774  }),
775  }}),
776  });
777  break;
778  default:
779  g_assert_not_reached();
780  break;
781  }
782  EXPECT_TRUE(fl_value_equal(args, expected_args));
783  (*call_count)++;
784 
785  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
786  },
787  &call_count);
788 
789  send_key_event(handler, GDK_KEY_Home);
790  EXPECT_EQ(call_count, 1);
791 }

References args, build_editing_delta(), build_list(), build_map(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_int(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), and user_data.

◆ TEST_F() [28/29]

TEST_F ( FlTextInputHandlerTest  ,
TextInputTypeNone   
)

Definition at line 710 of file fl_text_input_handler_test.cc.

710  {
711  set_client(messenger, {
712  .client_id = 1,
713  .input_type = "TextInputType.none",
714  });
715 
716  EXPECT_CALL(mock_gtk, gtk_im_context_focus_in).Times(0);
717  EXPECT_CALL(mock_gtk, gtk_im_context_focus_out);
718 
719  gboolean called = FALSE;
720  fl_mock_binary_messenger_invoke_json_method(
721  messenger, "flutter/textinput", "TextInput.show", nullptr,
722  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
723  gpointer user_data) {
724  gboolean* called = static_cast<gboolean*>(user_data);
725  *called = TRUE;
726 
727  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
728 
729  g_autoptr(FlValue) expected_result = fl_value_new_null();
731  FL_METHOD_SUCCESS_RESPONSE(response)),
732  expected_result));
733  },
734  &called);
735  EXPECT_TRUE(called);
736 }

References fl_method_success_response_get_result(), fl_value_equal(), fl_value_new_null(), g_autoptr(), set_client(), TRUE, and user_data.

◆ TEST_F() [29/29]

TEST_F ( FlTextInputHandlerTest  ,
UpdateConfig   
)

Definition at line 1248 of file fl_text_input_handler_test.cc.

1248  {
1249  set_client(messenger, {
1250  .client_id = 1,
1251  .input_action = "TextInputAction.none",
1252  });
1253 
1254  // Update config with a different input action
1255  gboolean called = FALSE;
1256  g_autoptr(FlValue) config = build_map({
1257  {"inputAction", fl_value_new_string("TextInputAction.send")},
1258  {"inputType", build_map({
1259  {"name", fl_value_new_string("TextInputType.text")},
1260  })},
1261  {"enableDeltaModel", fl_value_new_bool(false)},
1262  });
1263  fl_mock_binary_messenger_invoke_json_method(
1264  messenger, "flutter/textinput", "TextInput.updateConfig", config,
1265  [](FlMockBinaryMessenger* messenger, FlMethodResponse* response,
1266  gpointer user_data) {
1267  gboolean* called = static_cast<gboolean*>(user_data);
1268  *called = TRUE;
1269 
1270  EXPECT_TRUE(FL_IS_METHOD_SUCCESS_RESPONSE(response));
1271 
1272  g_autoptr(FlValue) expected_result = fl_value_new_null();
1274  FL_METHOD_SUCCESS_RESPONSE(response)),
1275  expected_result));
1276  },
1277  &called);
1278  EXPECT_TRUE(called);
1279 
1280  set_editing_state(messenger, {
1281  .text = "Flutter",
1282  .selection_base = 7,
1283  .selection_extent = 7,
1284  });
1285 
1286  // Verify the action was updated by checking perform action call
1287  int call_count = 0;
1288  fl_mock_binary_messenger_set_json_method_channel(
1289  messenger, "flutter/textinput",
1290  [](FlMockBinaryMessenger* messenger, GTask* task, const gchar* name,
1291  FlValue* args, gpointer user_data) {
1292  int* call_count = static_cast<int*>(user_data);
1293 
1294  EXPECT_STREQ(name, "TextInputClient.performAction");
1295  g_autoptr(FlValue) expected_args = build_list({
1296  fl_value_new_int(1), // client_id
1297  fl_value_new_string("TextInputAction.send"),
1298  });
1299  EXPECT_TRUE(fl_value_equal(args, expected_args));
1300  (*call_count)++;
1301 
1302  return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
1303  },
1304  &call_count);
1305 
1306  send_key_event(handler, GDK_KEY_Return);
1307  EXPECT_EQ(call_count, 1);
1308 }

References args, build_list(), build_map(), fl_method_success_response_get_result(), fl_method_success_response_new(), fl_value_equal(), fl_value_new_bool(), fl_value_new_int(), fl_value_new_null(), fl_value_new_string(), g_autoptr(), send_key_event(), set_client(), set_editing_state(), TRUE, and user_data.