Flutter Linux Embedder
fl_text_input_handler_test.cc File Reference
#include <utility>
#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/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"
#include "flutter/shell/platform/linux/testing/fl_test.h"
#include "flutter/shell/platform/linux/testing/mock_binary_messenger.h"
#include "flutter/shell/platform/linux/testing/mock_binary_messenger_response_handle.h"
#include "flutter/shell/platform/linux/testing/mock_im_context.h"
#include "flutter/shell/platform/linux/testing/mock_text_input_view_delegate.h"
#include "flutter/testing/testing.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

Go to the source code of this file.

Classes

class  MethodCallMatcher
 
struct  InputConfig
 
struct  EditingState
 
struct  EditingDelta
 

Functions

void printTo (FlMethodResponse *response, ::std::ostream *os)
 
 MATCHER_P (SuccessResponse, result, "")
 
 MATCHER_P (FlValueEq, value, "equal to "+::testing::PrintToString(value))
 
::testing::Matcher< GBytes * > MethodCall (const std::string &name, ::testing::Matcher< FlValue * > args)
 
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 send_key_event (FlTextInputHandler *handler, gint keyval, gint state=0)
 
 TEST (FlTextInputHandlerTest, MessageHandler)
 
 TEST (FlTextInputHandlerTest, SetClient)
 
 TEST (FlTextInputHandlerTest, Show)
 
 TEST (FlTextInputHandlerTest, Hide)
 
 TEST (FlTextInputHandlerTest, ClearClient)
 
 TEST (FlTextInputHandlerTest, PerformAction)
 
 TEST (FlTextInputHandlerTest, MultilineWithSendAction)
 
 TEST (FlTextInputHandlerTest, MoveCursor)
 
 TEST (FlTextInputHandlerTest, Select)
 
 TEST (FlTextInputHandlerTest, Composing)
 
 TEST (FlTextInputHandlerTest, SurroundingText)
 
 TEST (FlTextInputHandlerTest, SetMarkedTextRect)
 
 TEST (FlTextInputHandlerTest, TextInputTypeNone)
 
 TEST (FlTextInputHandlerTest, TextEditingDelta)
 
 TEST (FlTextInputHandlerTest, ComposingDelta)
 
 TEST (FlTextInputHandlerTest, NonComposingDelta)
 

Function Documentation

◆ build_editing_delta()

static FlValue* build_editing_delta ( EditingDelta  delta)
static

Definition at line 166 of file fl_text_input_handler_test.cc.

166  {
167  return build_map({
168  {"oldText", fl_value_new_string(delta.old_text)},
169  {"deltaText", fl_value_new_string(delta.delta_text)},
170  {"deltaStart", fl_value_new_int(delta.delta_start)},
171  {"deltaEnd", fl_value_new_int(delta.delta_end)},
172  {"selectionBase", fl_value_new_int(delta.selection_base)},
173  {"selectionExtent", fl_value_new_int(delta.selection_extent)},
174  {"selectionAffinity", fl_value_new_string("TextAffinity.downstream")},
175  {"selectionIsDirectional", fl_value_new_bool(false)},
176  {"composingBase", fl_value_new_int(delta.composing_base)},
177  {"composingExtent", fl_value_new_int(delta.composing_extent)},
178  });
179 }

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().

◆ build_editing_state()

static FlValue* build_editing_state ( EditingState  state)
static

Definition at line 143 of file fl_text_input_handler_test.cc.

143  {
144  return build_map({
145  {"text", fl_value_new_string(state.text)},
146  {"selectionBase", fl_value_new_int(state.selection_base)},
147  {"selectionExtent", fl_value_new_int(state.selection_extent)},
148  {"selectionAffinity", fl_value_new_string("TextAffinity.downstream")},
149  {"selectionIsDirectional", fl_value_new_bool(false)},
150  {"composingBase", fl_value_new_int(state.composing_base)},
151  {"composingExtent", fl_value_new_int(state.composing_extent)},
152  });
153 }

References build_map(), fl_value_new_bool(), fl_value_new_int(), fl_value_new_string(), and state.

Referenced by TEST().

◆ build_input_config()

static FlValue* build_input_config ( InputConfig  config)
static

Definition at line 122 of file fl_text_input_handler_test.cc.

122  {
123  return build_list({
124  fl_value_new_int(config.client_id),
125  build_map({
126  {"inputAction", fl_value_new_string(config.input_action)},
127  {"inputType", build_map({
128  {"name", fl_value_new_string(config.input_type)},
129  })},
130  {"enableDeltaModel", fl_value_new_bool(config.enable_delta_model)},
131  }),
132  });
133 }

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 TEST().

◆ build_list()

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

Definition at line 107 of file fl_text_input_handler_test.cc.

107  {
109  for (auto it = args.begin(); it != args.end(); ++it) {
111  }
112  return value;
113 }

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

Referenced by build_input_config(), and TEST().

◆ build_map()

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

Definition at line 99 of file fl_text_input_handler_test.cc.

99  {
101  for (auto it = args.begin(); it != args.end(); ++it) {
102  fl_value_set_string_take(value, it->first, it->second);
103  }
104  return value;
105 }

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().

◆ MATCHER_P() [1/2]

MATCHER_P ( FlValueEq  ,
value  ,
"equal to "+  ::testing::PrintToStringvalue 
)

Definition at line 39 of file fl_text_input_handler_test.cc.

39  {
40  return fl_value_equal(arg, value);
41 }

References fl_value_equal(), and value.

◆ MATCHER_P() [2/2]

MATCHER_P ( SuccessResponse  ,
result  ,
""   
)

Definition at line 27 of file fl_text_input_handler_test.cc.

27  {
28  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
29  g_autoptr(FlMethodResponse) response =
30  fl_method_codec_decode_response(FL_METHOD_CODEC(codec), arg, nullptr);
31  if (fl_value_equal(fl_method_response_get_result(response, nullptr),
32  result)) {
33  return true;
34  }
35  *result_listener << ::testing::PrintToString(response);
36  return false;
37 }

References fl_json_method_codec_new(), fl_method_codec_decode_response(), fl_method_response_get_result(), fl_value_equal(), and result.

◆ MethodCall()

::testing::Matcher<GBytes*> MethodCall ( const std::string &  name,
::testing::Matcher< FlValue * >  args 
)

Definition at line 94 of file fl_text_input_handler_test.cc.

95  {
96  return MethodCallMatcher(::testing::StrEq(name), std::move(args));
97 }

References args.

Referenced by TEST().

◆ printTo()

void printTo ( FlMethodResponse *  response,
::std::ostream *  os 
)

Definition at line 22 of file fl_text_input_handler_test.cc.

22  {
23  *os << ::testing::PrintToString(
24  fl_method_response_get_result(response, nullptr));
25 }

References fl_method_response_get_result().

◆ send_key_event()

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

Definition at line 181 of file fl_text_input_handler_test.cc.

183  {
184  GdkEvent* gdk_event = gdk_event_new(GDK_KEY_PRESS);
185  gdk_event->key.keyval = keyval;
186  gdk_event->key.state = state;
187  g_autoptr(FlKeyEvent) key_event = fl_key_event_new_from_gdk_event(gdk_event);
188  fl_text_input_handler_filter_keypress(handler, key_event);
189 }

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

Referenced by fl_key_embedder_responder_new(), and TEST().

◆ TEST() [1/16]

TEST ( FlTextInputHandlerTest  ,
ClearClient   
)

Definition at line 276 of file fl_text_input_handler_test.cc.

276  {
277  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
278  ::testing::NiceMock<flutter::testing::MockIMContext> context;
279  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
280 
281  g_autoptr(FlTextInputHandler) handler =
282  fl_text_input_handler_new(messenger, context, delegate);
283  EXPECT_NE(handler, nullptr);
284 
285  g_autoptr(FlValue) null = fl_value_new_null();
286  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
287  ::testing::Eq<FlBinaryMessenger*>(messenger),
288  ::testing::_, SuccessResponse(null), ::testing::_))
289  .WillOnce(::testing::Return(true));
290 
291  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
292  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
293  FL_METHOD_CODEC(codec), "TextInput.clearClient", nullptr, nullptr);
294 
295  messenger.ReceiveMessage("flutter/textinput", message);
296 }

References fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), and fl_value_new_null().

◆ TEST() [2/16]

TEST ( FlTextInputHandlerTest  ,
Composing   
)

Definition at line 595 of file fl_text_input_handler_test.cc.

595  {
596  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
597  ::testing::NiceMock<flutter::testing::MockIMContext> context;
598  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
599 
600  g_autoptr(FlTextInputHandler) handler =
601  fl_text_input_handler_new(messenger, context, delegate);
602  EXPECT_NE(handler, nullptr);
603 
604  g_signal_emit_by_name(context, "preedit-start", nullptr);
605 
606  // update
607  EXPECT_CALL(context,
608  gtk_im_context_get_preedit_string(
609  ::testing::Eq<GtkIMContext*>(context),
610  ::testing::A<gchar**>(), ::testing::_, ::testing::A<gint*>()))
611  .WillOnce(
612  ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup("Flutter")),
613  ::testing::SetArgPointee<3>(0)));
614 
615  g_autoptr(FlValue) state = build_list({
616  fl_value_new_int(-1), // client_id
618  .text = "Flutter",
619  .selection_base = 0,
620  .selection_extent = 0,
621  .composing_base = 0,
622  .composing_extent = 7,
623  }),
624  });
625 
626  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
627  ::testing::Eq<FlBinaryMessenger*>(messenger),
628  ::testing::StrEq("flutter/textinput"),
629  MethodCall("TextInputClient.updateEditingState",
630  FlValueEq(state)),
631  ::testing::_, ::testing::_, ::testing::_));
632 
633  g_signal_emit_by_name(context, "preedit-changed", nullptr);
634 
635  // commit
636  g_autoptr(FlValue) commit = build_list({
637  fl_value_new_int(-1), // client_id
639  .text = "engine",
640  .selection_base = 6,
641  .selection_extent = 6,
642  }),
643  });
644 
645  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
646  ::testing::Eq<FlBinaryMessenger*>(messenger),
647  ::testing::StrEq("flutter/textinput"),
648  MethodCall("TextInputClient.updateEditingState",
649  FlValueEq(commit)),
650  ::testing::_, ::testing::_, ::testing::_));
651 
652  g_signal_emit_by_name(context, "commit", "engine", nullptr);
653 
654  // end
655  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
656  ::testing::Eq<FlBinaryMessenger*>(messenger),
657  ::testing::StrEq("flutter/textinput"),
658  MethodCall("TextInputClient.updateEditingState",
659  ::testing::_),
660  ::testing::_, ::testing::_, ::testing::_));
661 
662  g_signal_emit_by_name(context, "preedit-end", nullptr);
663 }

References build_editing_state(), build_list(), fl_binary_messenger_send_on_channel(), fl_text_input_handler_new(), fl_value_new_int(), MethodCall(), and state.

◆ TEST() [3/16]

TEST ( FlTextInputHandlerTest  ,
ComposingDelta   
)

Definition at line 933 of file fl_text_input_handler_test.cc.

933  {
934  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
935  ::testing::NiceMock<flutter::testing::MockIMContext> context;
936  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
937 
938  g_autoptr(FlTextInputHandler) handler =
939  fl_text_input_handler_new(messenger, context, delegate);
940  EXPECT_NE(handler, nullptr);
941 
942  // set config
943  g_autoptr(FlValue) args = build_input_config({
944  .client_id = 1,
945  .enable_delta_model = true,
946  });
947  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
949  FL_METHOD_CODEC(codec), "TextInput.setClient", args, nullptr);
950 
951  g_autoptr(FlValue) null = fl_value_new_null();
952  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
953  ::testing::Eq<FlBinaryMessenger*>(messenger),
954  ::testing::A<FlBinaryMessengerResponseHandle*>(),
955  SuccessResponse(null), ::testing::A<GError**>()))
956  .WillOnce(::testing::Return(true));
957 
958  messenger.ReceiveMessage("flutter/textinput", set_client);
959 
960  g_signal_emit_by_name(context, "preedit-start", nullptr);
961 
962  // update
963  EXPECT_CALL(context,
964  gtk_im_context_get_preedit_string(
965  ::testing::Eq<GtkIMContext*>(context),
966  ::testing::A<gchar**>(), ::testing::_, ::testing::A<gint*>()))
967  .WillOnce(
968  ::testing::DoAll(::testing::SetArgPointee<1>(g_strdup("Flutter ")),
969  ::testing::SetArgPointee<3>(8)));
970 
971  g_autoptr(FlValue) update = build_list({
972  fl_value_new_int(1), // client_id
973  build_map({{
974  "deltas",
975  build_list({
977  .old_text = "",
978  .delta_text = "Flutter ",
979  .delta_start = 0,
980  .delta_end = 0,
981  .selection_base = 8,
982  .selection_extent = 8,
983  .composing_base = 0,
984  .composing_extent = 8,
985  }),
986  }),
987  }}),
988  });
989 
990  EXPECT_CALL(messenger,
992  ::testing::Eq<FlBinaryMessenger*>(messenger),
993  ::testing::StrEq("flutter/textinput"),
994  MethodCall("TextInputClient.updateEditingStateWithDeltas",
995  FlValueEq(update)),
996  ::testing::_, ::testing::_, ::testing::_));
997 
998  g_signal_emit_by_name(context, "preedit-changed", nullptr);
999 
1000  // commit
1001  g_autoptr(FlValue) commit = build_list({
1002  fl_value_new_int(1), // client_id
1003  build_map({{
1004  "deltas",
1005  build_list({
1007  .old_text = "Flutter ",
1008  .delta_text = "Flutter engine",
1009  .delta_start = 0,
1010  .delta_end = 8,
1011  .selection_base = 14,
1012  .selection_extent = 14,
1013  .composing_base = -1,
1014  .composing_extent = -1,
1015  }),
1016  }),
1017  }}),
1018  });
1019 
1020  EXPECT_CALL(messenger,
1022  ::testing::Eq<FlBinaryMessenger*>(messenger),
1023  ::testing::StrEq("flutter/textinput"),
1024  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1025  FlValueEq(commit)),
1026  ::testing::_, ::testing::_, ::testing::_));
1027 
1028  g_signal_emit_by_name(context, "commit", "Flutter engine", nullptr);
1029 
1030  // end
1031  g_autoptr(FlValue) end = build_list({
1032  fl_value_new_int(1), // client_id
1033  build_map({{
1034  "deltas",
1035  build_list({
1037  .old_text = "Flutter engine",
1038  .selection_base = 14,
1039  .selection_extent = 14,
1040  }),
1041  }),
1042  }}),
1043  });
1044 
1045  EXPECT_CALL(messenger,
1047  ::testing::Eq<FlBinaryMessenger*>(messenger),
1048  ::testing::StrEq("flutter/textinput"),
1049  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1050  FlValueEq(end)),
1051  ::testing::_, ::testing::_, ::testing::_));
1052 
1053  g_signal_emit_by_name(context, "preedit-end", nullptr);
1054 }

References args, build_editing_delta(), build_input_config(), build_list(), build_map(), end, fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), and set_client().

◆ TEST() [4/16]

TEST ( FlTextInputHandlerTest  ,
Hide   
)

Definition at line 251 of file fl_text_input_handler_test.cc.

251  {
252  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
253  ::testing::NiceMock<flutter::testing::MockIMContext> context;
254  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
255 
256  g_autoptr(FlTextInputHandler) handler =
257  fl_text_input_handler_new(messenger, context, delegate);
258  EXPECT_NE(handler, nullptr);
259 
260  EXPECT_CALL(context,
261  gtk_im_context_focus_out(::testing::Eq<GtkIMContext*>(context)));
262 
263  g_autoptr(FlValue) null = fl_value_new_null();
264  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
265  ::testing::Eq<FlBinaryMessenger*>(messenger),
266  ::testing::_, SuccessResponse(null), ::testing::_))
267  .WillOnce(::testing::Return(true));
268 
269  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
270  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
271  FL_METHOD_CODEC(codec), "TextInput.hide", nullptr, nullptr);
272 
273  messenger.ReceiveMessage("flutter/textinput", message);
274 }

References fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), and fl_value_new_null().

◆ TEST() [5/16]

TEST ( FlTextInputHandlerTest  ,
MessageHandler   
)

Definition at line 191 of file fl_text_input_handler_test.cc.

191  {
192  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
193  ::testing::NiceMock<flutter::testing::MockIMContext> context;
194  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
195 
196  g_autoptr(FlTextInputHandler) handler =
197  fl_text_input_handler_new(messenger, context, delegate);
198  EXPECT_NE(handler, nullptr);
199 
200  EXPECT_TRUE(messenger.HasMessageHandler("flutter/textinput"));
201 }

References fl_text_input_handler_new().

◆ TEST() [6/16]

TEST ( FlTextInputHandlerTest  ,
MoveCursor   
)

Definition at line 439 of file fl_text_input_handler_test.cc.

439  {
440  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
441  ::testing::NiceMock<flutter::testing::MockIMContext> context;
442  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
443 
444  g_autoptr(FlTextInputHandler) handler =
445  fl_text_input_handler_new(messenger, context, delegate);
446  EXPECT_NE(handler, nullptr);
447 
448  // set input config
449  g_autoptr(FlValue) config = build_input_config({.client_id = 1});
450  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
452  FL_METHOD_CODEC(codec), "TextInput.setClient", config, nullptr);
453 
454  g_autoptr(FlValue) null = fl_value_new_null();
455  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
456  ::testing::Eq<FlBinaryMessenger*>(messenger),
457  ::testing::_, SuccessResponse(null), ::testing::_))
458  .WillOnce(::testing::Return(true));
459 
460  messenger.ReceiveMessage("flutter/textinput", set_client);
461 
462  // set editing state
463  g_autoptr(FlValue) state = build_editing_state({
464  .text = "Flutter",
465  .selection_base = 4,
466  .selection_extent = 4,
467  });
468  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
469  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
470 
471  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
472  ::testing::Eq<FlBinaryMessenger*>(messenger),
473  ::testing::_, SuccessResponse(null), ::testing::_))
474  .WillOnce(::testing::Return(true));
475 
476  messenger.ReceiveMessage("flutter/textinput", set_state);
477 
478  // move cursor to beginning
479  g_autoptr(FlValue) beginning = build_list({
480  fl_value_new_int(1), // client_id
482  .text = "Flutter",
483  .selection_base = 0,
484  .selection_extent = 0,
485  }),
486  });
487 
488  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
489  ::testing::Eq<FlBinaryMessenger*>(messenger),
490  ::testing::StrEq("flutter/textinput"),
491  MethodCall("TextInputClient.updateEditingState",
492  FlValueEq(beginning)),
493  ::testing::_, ::testing::_, ::testing::_));
494 
495  send_key_event(handler, GDK_KEY_Home);
496 
497  // move cursor to end
498  g_autoptr(FlValue) end = build_list({
499  fl_value_new_int(1), // client_id
501  .text = "Flutter",
502  .selection_base = 7,
503  .selection_extent = 7,
504  }),
505  });
506 
507  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
508  ::testing::Eq<FlBinaryMessenger*>(messenger),
509  ::testing::StrEq("flutter/textinput"),
510  MethodCall("TextInputClient.updateEditingState",
511  FlValueEq(end)),
512  ::testing::_, ::testing::_, ::testing::_));
513 
514  send_key_event(handler, GDK_KEY_End);
515 }

References build_editing_state(), build_input_config(), build_list(), end, fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [7/16]

TEST ( FlTextInputHandlerTest  ,
MultilineWithSendAction   
)

Definition at line 375 of file fl_text_input_handler_test.cc.

375  {
376  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
377  ::testing::NiceMock<flutter::testing::MockIMContext> context;
378  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
379 
380  g_autoptr(FlTextInputHandler) handler =
381  fl_text_input_handler_new(messenger, context, delegate);
382  EXPECT_NE(handler, nullptr);
383 
384  // Set input config.
385  g_autoptr(FlValue) config = build_input_config({
386  .client_id = 1,
387  .input_type = "TextInputType.multiline",
388  .input_action = "TextInputAction.send",
389  });
390  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
392  FL_METHOD_CODEC(codec), "TextInput.setClient", config, nullptr);
393 
394  g_autoptr(FlValue) null = fl_value_new_null();
395  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
396  ::testing::Eq<FlBinaryMessenger*>(messenger),
397  ::testing::_, SuccessResponse(null), ::testing::_))
398  .WillOnce(::testing::Return(true));
399 
400  messenger.ReceiveMessage("flutter/textinput", set_client);
401 
402  // Set editing state.
403  g_autoptr(FlValue) state = build_editing_state({
404  .text = "Flutter",
405  .selection_base = 7,
406  .selection_extent = 7,
407  });
408  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
409  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
410 
411  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
412  ::testing::Eq<FlBinaryMessenger*>(messenger),
413  ::testing::_, SuccessResponse(null), ::testing::_))
414  .WillOnce(::testing::Return(true));
415 
416  messenger.ReceiveMessage("flutter/textinput", set_state);
417 
418  // Perform action.
419  g_autoptr(FlValue) action = build_list({
420  fl_value_new_int(1), // client_id
421  fl_value_new_string("TextInputAction.send"),
422  });
423 
424  // Because the input action is not set to TextInputAction.newline, the next
425  // expected call is "TextInputClient.performAction". If the input action was
426  // set to TextInputAction.newline the next call would be
427  // "TextInputClient.updateEditingState" (this case is tested in the test named
428  // 'PerformAction').
429  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
430  ::testing::Eq<FlBinaryMessenger*>(messenger),
431  ::testing::StrEq("flutter/textinput"),
432  MethodCall("TextInputClient.performAction",
433  FlValueEq(action)),
434  ::testing::_, ::testing::_, ::testing::_));
435 
436  send_key_event(handler, GDK_KEY_Return);
437 }

References build_editing_state(), build_input_config(), build_list(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), fl_value_new_string(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [8/16]

TEST ( FlTextInputHandlerTest  ,
NonComposingDelta   
)

Definition at line 1056 of file fl_text_input_handler_test.cc.

1056  {
1057  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
1058  ::testing::NiceMock<flutter::testing::MockIMContext> context;
1059  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
1060 
1061  g_autoptr(FlTextInputHandler) handler =
1062  fl_text_input_handler_new(messenger, context, delegate);
1063  EXPECT_NE(handler, nullptr);
1064 
1065  // set config
1066  g_autoptr(FlValue) args = build_input_config({
1067  .client_id = 1,
1068  .enable_delta_model = true,
1069  });
1070  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
1071  g_autoptr(GBytes) set_client = fl_method_codec_encode_method_call(
1072  FL_METHOD_CODEC(codec), "TextInput.setClient", args, nullptr);
1073 
1074  g_autoptr(FlValue) null = fl_value_new_null();
1075  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
1076  ::testing::Eq<FlBinaryMessenger*>(messenger),
1077  ::testing::A<FlBinaryMessengerResponseHandle*>(),
1078  SuccessResponse(null), ::testing::A<GError**>()))
1079  .WillOnce(::testing::Return(true));
1080 
1081  messenger.ReceiveMessage("flutter/textinput", set_client);
1082 
1083  // commit F
1084  g_autoptr(FlValue) commit = build_list({
1085  fl_value_new_int(1), // client_id
1086  build_map({{
1087  "deltas",
1088  build_list({
1090  .old_text = "",
1091  .delta_text = "F",
1092  .delta_start = 0,
1093  .delta_end = 0,
1094  .selection_base = 1,
1095  .selection_extent = 1,
1096  .composing_base = -1,
1097  .composing_extent = -1,
1098  }),
1099  }),
1100  }}),
1101  });
1102 
1103  EXPECT_CALL(messenger,
1105  ::testing::Eq<FlBinaryMessenger*>(messenger),
1106  ::testing::StrEq("flutter/textinput"),
1107  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1108  FlValueEq(commit)),
1109  ::testing::_, ::testing::_, ::testing::_));
1110 
1111  g_signal_emit_by_name(context, "commit", "F", nullptr);
1112 
1113  // commit l
1114  g_autoptr(FlValue) commitL = build_list({
1115  fl_value_new_int(1), // client_id
1116  build_map({{
1117  "deltas",
1118  build_list({
1120  .old_text = "F",
1121  .delta_text = "l",
1122  .delta_start = 1,
1123  .delta_end = 1,
1124  .selection_base = 2,
1125  .selection_extent = 2,
1126  .composing_base = -1,
1127  .composing_extent = -1,
1128  }),
1129  }),
1130  }}),
1131  });
1132 
1133  EXPECT_CALL(messenger,
1135  ::testing::Eq<FlBinaryMessenger*>(messenger),
1136  ::testing::StrEq("flutter/textinput"),
1137  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1138  FlValueEq(commitL)),
1139  ::testing::_, ::testing::_, ::testing::_));
1140 
1141  g_signal_emit_by_name(context, "commit", "l", nullptr);
1142 
1143  // commit u
1144  g_autoptr(FlValue) commitU = build_list({
1145  fl_value_new_int(1), // client_id
1146  build_map({{
1147  "deltas",
1148  build_list({
1150  .old_text = "Fl",
1151  .delta_text = "u",
1152  .delta_start = 2,
1153  .delta_end = 2,
1154  .selection_base = 3,
1155  .selection_extent = 3,
1156  .composing_base = -1,
1157  .composing_extent = -1,
1158  }),
1159  }),
1160  }}),
1161  });
1162 
1163  EXPECT_CALL(messenger,
1165  ::testing::Eq<FlBinaryMessenger*>(messenger),
1166  ::testing::StrEq("flutter/textinput"),
1167  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1168  FlValueEq(commitU)),
1169  ::testing::_, ::testing::_, ::testing::_));
1170 
1171  g_signal_emit_by_name(context, "commit", "u", nullptr);
1172 
1173  // commit t
1174  g_autoptr(FlValue) commitTa = build_list({
1175  fl_value_new_int(1), // client_id
1176  build_map({{
1177  "deltas",
1178  build_list({
1180  .old_text = "Flu",
1181  .delta_text = "t",
1182  .delta_start = 3,
1183  .delta_end = 3,
1184  .selection_base = 4,
1185  .selection_extent = 4,
1186  .composing_base = -1,
1187  .composing_extent = -1,
1188  }),
1189  }),
1190  }}),
1191  });
1192 
1193  EXPECT_CALL(messenger,
1195  ::testing::Eq<FlBinaryMessenger*>(messenger),
1196  ::testing::StrEq("flutter/textinput"),
1197  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1198  FlValueEq(commitTa)),
1199  ::testing::_, ::testing::_, ::testing::_));
1200 
1201  g_signal_emit_by_name(context, "commit", "t", nullptr);
1202 
1203  // commit t again
1204  g_autoptr(FlValue) commitTb = build_list({
1205  fl_value_new_int(1), // client_id
1206  build_map({{
1207  "deltas",
1208  build_list({
1210  .old_text = "Flut",
1211  .delta_text = "t",
1212  .delta_start = 4,
1213  .delta_end = 4,
1214  .selection_base = 5,
1215  .selection_extent = 5,
1216  .composing_base = -1,
1217  .composing_extent = -1,
1218  }),
1219  }),
1220  }}),
1221  });
1222 
1223  EXPECT_CALL(messenger,
1225  ::testing::Eq<FlBinaryMessenger*>(messenger),
1226  ::testing::StrEq("flutter/textinput"),
1227  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1228  FlValueEq(commitTb)),
1229  ::testing::_, ::testing::_, ::testing::_));
1230 
1231  g_signal_emit_by_name(context, "commit", "t", nullptr);
1232 
1233  // commit e
1234  g_autoptr(FlValue) commitE = build_list({
1235  fl_value_new_int(1), // client_id
1236  build_map({{
1237  "deltas",
1238  build_list({
1240  .old_text = "Flutt",
1241  .delta_text = "e",
1242  .delta_start = 5,
1243  .delta_end = 5,
1244  .selection_base = 6,
1245  .selection_extent = 6,
1246  .composing_base = -1,
1247  .composing_extent = -1,
1248  }),
1249  }),
1250  }}),
1251  });
1252 
1253  EXPECT_CALL(messenger,
1255  ::testing::Eq<FlBinaryMessenger*>(messenger),
1256  ::testing::StrEq("flutter/textinput"),
1257  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1258  FlValueEq(commitE)),
1259  ::testing::_, ::testing::_, ::testing::_));
1260 
1261  g_signal_emit_by_name(context, "commit", "e", nullptr);
1262 
1263  // commit r
1264  g_autoptr(FlValue) commitR = build_list({
1265  fl_value_new_int(1), // client_id
1266  build_map({{
1267  "deltas",
1268  build_list({
1270  .old_text = "Flutte",
1271  .delta_text = "r",
1272  .delta_start = 6,
1273  .delta_end = 6,
1274  .selection_base = 7,
1275  .selection_extent = 7,
1276  .composing_base = -1,
1277  .composing_extent = -1,
1278  }),
1279  }),
1280  }}),
1281  });
1282 
1283  EXPECT_CALL(messenger,
1285  ::testing::Eq<FlBinaryMessenger*>(messenger),
1286  ::testing::StrEq("flutter/textinput"),
1287  MethodCall("TextInputClient.updateEditingStateWithDeltas",
1288  FlValueEq(commitR)),
1289  ::testing::_, ::testing::_, ::testing::_));
1290 
1291  g_signal_emit_by_name(context, "commit", "r", nullptr);
1292 }

References args, build_editing_delta(), build_input_config(), build_list(), build_map(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), and set_client().

◆ TEST() [9/16]

TEST ( FlTextInputHandlerTest  ,
PerformAction   
)

Definition at line 298 of file fl_text_input_handler_test.cc.

298  {
299  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
300  ::testing::NiceMock<flutter::testing::MockIMContext> context;
301  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
302 
303  g_autoptr(FlTextInputHandler) handler =
304  fl_text_input_handler_new(messenger, context, delegate);
305  EXPECT_NE(handler, nullptr);
306 
307  // set input config
308  g_autoptr(FlValue) config = build_input_config({
309  .client_id = 1,
310  .input_type = "TextInputType.multiline",
311  .input_action = "TextInputAction.newline",
312  });
313  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
315  FL_METHOD_CODEC(codec), "TextInput.setClient", config, nullptr);
316 
317  g_autoptr(FlValue) null = fl_value_new_null();
318  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
319  ::testing::Eq<FlBinaryMessenger*>(messenger),
320  ::testing::_, SuccessResponse(null), ::testing::_))
321  .WillOnce(::testing::Return(true));
322 
323  messenger.ReceiveMessage("flutter/textinput", set_client);
324 
325  // set editing state
326  g_autoptr(FlValue) state = build_editing_state({
327  .text = "Flutter",
328  .selection_base = 7,
329  .selection_extent = 7,
330  });
331  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
332  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
333 
334  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
335  ::testing::Eq<FlBinaryMessenger*>(messenger),
336  ::testing::_, SuccessResponse(null), ::testing::_))
337  .WillOnce(::testing::Return(true));
338 
339  messenger.ReceiveMessage("flutter/textinput", set_state);
340 
341  // update editing state
342  g_autoptr(FlValue) new_state = build_list({
343  fl_value_new_int(1), // client_id
345  .text = "Flutter\n",
346  .selection_base = 8,
347  .selection_extent = 8,
348  }),
349  });
350 
351  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
352  ::testing::Eq<FlBinaryMessenger*>(messenger),
353  ::testing::StrEq("flutter/textinput"),
354  MethodCall("TextInputClient.updateEditingState",
355  FlValueEq(new_state)),
356  ::testing::_, ::testing::_, ::testing::_));
357 
358  // perform action
359  g_autoptr(FlValue) action = build_list({
360  fl_value_new_int(1), // client_id
361  fl_value_new_string("TextInputAction.newline"),
362  });
363 
364  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
365  ::testing::Eq<FlBinaryMessenger*>(messenger),
366  ::testing::StrEq("flutter/textinput"),
367  MethodCall("TextInputClient.performAction",
368  FlValueEq(action)),
369  ::testing::_, ::testing::_, ::testing::_));
370 
371  send_key_event(handler, GDK_KEY_Return);
372 }

References build_editing_state(), build_input_config(), build_list(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), fl_value_new_string(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [10/16]

TEST ( FlTextInputHandlerTest  ,
Select   
)

Definition at line 517 of file fl_text_input_handler_test.cc.

517  {
518  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
519  ::testing::NiceMock<flutter::testing::MockIMContext> context;
520  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
521 
522  g_autoptr(FlTextInputHandler) handler =
523  fl_text_input_handler_new(messenger, context, delegate);
524  EXPECT_NE(handler, nullptr);
525 
526  // set input config
527  g_autoptr(FlValue) config = build_input_config({.client_id = 1});
528  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
530  FL_METHOD_CODEC(codec), "TextInput.setClient", config, nullptr);
531 
532  g_autoptr(FlValue) null = fl_value_new_null();
533  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
534  ::testing::Eq<FlBinaryMessenger*>(messenger),
535  ::testing::_, SuccessResponse(null), ::testing::_))
536  .WillOnce(::testing::Return(true));
537 
538  messenger.ReceiveMessage("flutter/textinput", set_client);
539 
540  // set editing state
541  g_autoptr(FlValue) state = build_editing_state({
542  .text = "Flutter",
543  .selection_base = 4,
544  .selection_extent = 4,
545  });
546  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
547  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
548 
549  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
550  ::testing::Eq<FlBinaryMessenger*>(messenger),
551  ::testing::_, SuccessResponse(null), ::testing::_))
552  .WillOnce(::testing::Return(true));
553 
554  messenger.ReceiveMessage("flutter/textinput", set_state);
555 
556  // select to end
557  g_autoptr(FlValue) select_to_end = build_list({
558  fl_value_new_int(1), // client_id
560  .text = "Flutter",
561  .selection_base = 4,
562  .selection_extent = 7,
563  }),
564  });
565 
566  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
567  ::testing::Eq<FlBinaryMessenger*>(messenger),
568  ::testing::StrEq("flutter/textinput"),
569  MethodCall("TextInputClient.updateEditingState",
570  FlValueEq(select_to_end)),
571  ::testing::_, ::testing::_, ::testing::_));
572 
573  send_key_event(handler, GDK_KEY_End, GDK_SHIFT_MASK);
574 
575  // select to beginning
576  g_autoptr(FlValue) select_to_beginning = build_list({
577  fl_value_new_int(1), // client_id
579  .text = "Flutter",
580  .selection_base = 4,
581  .selection_extent = 0,
582  }),
583  });
584 
585  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
586  ::testing::Eq<FlBinaryMessenger*>(messenger),
587  ::testing::StrEq("flutter/textinput"),
588  MethodCall("TextInputClient.updateEditingState",
589  FlValueEq(select_to_beginning)),
590  ::testing::_, ::testing::_, ::testing::_));
591 
592  send_key_event(handler, GDK_KEY_Home, GDK_SHIFT_MASK);
593 }

References build_editing_state(), build_input_config(), build_list(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [11/16]

TEST ( FlTextInputHandlerTest  ,
SetClient   
)

Definition at line 203 of file fl_text_input_handler_test.cc.

203  {
204  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
205  ::testing::NiceMock<flutter::testing::MockIMContext> context;
206  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
207 
208  g_autoptr(FlTextInputHandler) handler =
209  fl_text_input_handler_new(messenger, context, delegate);
210  EXPECT_NE(handler, nullptr);
211 
212  g_autoptr(FlValue) args = build_input_config({.client_id = 1});
213  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
214  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
215  FL_METHOD_CODEC(codec), "TextInput.setClient", args, nullptr);
216 
217  g_autoptr(FlValue) null = fl_value_new_null();
218  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
219  ::testing::Eq<FlBinaryMessenger*>(messenger),
220  ::testing::_, SuccessResponse(null), ::testing::_))
221  .WillOnce(::testing::Return(true));
222 
223  messenger.ReceiveMessage("flutter/textinput", message);
224 }

References args, build_input_config(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), and fl_value_new_null().

◆ TEST() [12/16]

TEST ( FlTextInputHandlerTest  ,
SetMarkedTextRect   
)

Definition at line 735 of file fl_text_input_handler_test.cc.

735  {
736  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
737  ::testing::NiceMock<flutter::testing::MockIMContext> context;
738  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
739 
740  g_autoptr(FlTextInputHandler) handler =
741  fl_text_input_handler_new(messenger, context, delegate);
742  EXPECT_NE(handler, nullptr);
743 
744  g_signal_emit_by_name(context, "preedit-start", nullptr);
745 
746  // set editable size and transform
747  g_autoptr(FlValue) size_and_transform = build_map({
748  {
749  "transform",
750  build_list({
760  fl_value_new_float(10),
761  fl_value_new_float(11),
762  fl_value_new_float(12),
763  fl_value_new_float(13),
764  fl_value_new_float(14),
765  fl_value_new_float(15),
766  fl_value_new_float(16),
767  }),
768  },
769  });
770  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
771  g_autoptr(GBytes) set_editable_size_and_transform =
773  FL_METHOD_CODEC(codec), "TextInput.setEditableSizeAndTransform",
774  size_and_transform, nullptr);
775 
776  g_autoptr(FlValue) null = fl_value_new_null();
777  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
778  ::testing::Eq<FlBinaryMessenger*>(messenger),
779  ::testing::_, SuccessResponse(null), ::testing::_))
780  .WillOnce(::testing::Return(true));
781 
782  messenger.ReceiveMessage("flutter/textinput",
784 
785  // set marked text rect
786  g_autoptr(FlValue) rect = build_map({
787  {"x", fl_value_new_float(1)},
788  {"y", fl_value_new_float(2)},
789  {"width", fl_value_new_float(3)},
790  {"height", fl_value_new_float(4)},
791  });
793  FL_METHOD_CODEC(codec), "TextInput.setMarkedTextRect", rect, nullptr);
794 
795  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
796  ::testing::Eq<FlBinaryMessenger*>(messenger),
797  ::testing::_, SuccessResponse(null), ::testing::_))
798  .WillOnce(::testing::Return(true));
799 
801  ::testing::Eq<FlTextInputViewDelegate*>(delegate),
802  ::testing::Eq(27), ::testing::Eq(32), ::testing::_,
803  ::testing::_))
804  .WillOnce(::testing::DoAll(::testing::SetArgPointee<3>(123),
805  ::testing::SetArgPointee<4>(456)));
806 
807  EXPECT_CALL(context, gtk_im_context_set_cursor_location(
808  ::testing::Eq<GtkIMContext*>(context),
809  ::testing::Pointee(::testing::AllOf(
810  ::testing::Field(&GdkRectangle::x, 123),
811  ::testing::Field(&GdkRectangle::y, 456),
812  ::testing::Field(&GdkRectangle::width, 0),
813  ::testing::Field(&GdkRectangle::height, 0)))));
814 
815  messenger.ReceiveMessage("flutter/textinput", set_marked_text_rect);
816 }

References build_list(), build_map(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_text_input_view_delegate_translate_coordinates(), fl_value_new_float(), fl_value_new_null(), height, set_editable_size_and_transform(), set_marked_text_rect(), and width.

◆ TEST() [13/16]

TEST ( FlTextInputHandlerTest  ,
Show   
)

Definition at line 226 of file fl_text_input_handler_test.cc.

226  {
227  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
228  ::testing::NiceMock<flutter::testing::MockIMContext> context;
229  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
230 
231  g_autoptr(FlTextInputHandler) handler =
232  fl_text_input_handler_new(messenger, context, delegate);
233  EXPECT_NE(handler, nullptr);
234 
235  EXPECT_CALL(context,
236  gtk_im_context_focus_in(::testing::Eq<GtkIMContext*>(context)));
237 
238  g_autoptr(FlValue) null = fl_value_new_null();
239  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
240  ::testing::Eq<FlBinaryMessenger*>(messenger),
241  ::testing::_, SuccessResponse(null), ::testing::_))
242  .WillOnce(::testing::Return(true));
243 
244  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
245  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
246  FL_METHOD_CODEC(codec), "TextInput.show", nullptr, nullptr);
247 
248  messenger.ReceiveMessage("flutter/textinput", message);
249 }

References fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), and fl_value_new_null().

◆ TEST() [14/16]

TEST ( FlTextInputHandlerTest  ,
SurroundingText   
)

Definition at line 665 of file fl_text_input_handler_test.cc.

665  {
666  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
667  ::testing::NiceMock<flutter::testing::MockIMContext> context;
668  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
669 
670  g_autoptr(FlTextInputHandler) handler =
671  fl_text_input_handler_new(messenger, context, delegate);
672  EXPECT_NE(handler, nullptr);
673 
674  // set input config
675  g_autoptr(FlValue) config = build_input_config({.client_id = 1});
676  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
678  FL_METHOD_CODEC(codec), "TextInput.setClient", config, nullptr);
679 
680  g_autoptr(FlValue) null = fl_value_new_null();
681  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
682  ::testing::Eq<FlBinaryMessenger*>(messenger),
683  ::testing::_, SuccessResponse(null), ::testing::_))
684  .WillOnce(::testing::Return(true));
685 
686  messenger.ReceiveMessage("flutter/textinput", set_client);
687 
688  // set editing state
689  g_autoptr(FlValue) state = build_editing_state({
690  .text = "Flutter",
691  .selection_base = 3,
692  .selection_extent = 3,
693  });
694  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
695  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
696 
697  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
698  ::testing::Eq<FlBinaryMessenger*>(messenger),
699  ::testing::_, SuccessResponse(null), ::testing::_))
700  .WillOnce(::testing::Return(true));
701 
702  messenger.ReceiveMessage("flutter/textinput", set_state);
703 
704  // retrieve
705  EXPECT_CALL(context, gtk_im_context_set_surrounding(
706  ::testing::Eq<GtkIMContext*>(context),
707  ::testing::StrEq("Flutter"), 7, 3));
708 
709  gboolean retrieved = false;
710  g_signal_emit_by_name(context, "retrieve-surrounding", &retrieved, nullptr);
711  EXPECT_TRUE(retrieved);
712 
713  // delete
714  g_autoptr(FlValue) update = build_list({
715  fl_value_new_int(1), // client_id
717  .text = "Flutr",
718  .selection_base = 3,
719  .selection_extent = 3,
720  }),
721  });
722 
723  EXPECT_CALL(messenger, fl_binary_messenger_send_on_channel(
724  ::testing::Eq<FlBinaryMessenger*>(messenger),
725  ::testing::StrEq("flutter/textinput"),
726  MethodCall("TextInputClient.updateEditingState",
727  FlValueEq(update)),
728  ::testing::_, ::testing::_, ::testing::_));
729 
730  gboolean deleted = false;
731  g_signal_emit_by_name(context, "delete-surrounding", 1, 2, &deleted, nullptr);
732  EXPECT_TRUE(deleted);
733 }

References build_editing_state(), build_input_config(), build_list(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), set_client(), and state.

◆ TEST() [15/16]

TEST ( FlTextInputHandlerTest  ,
TextEditingDelta   
)

Definition at line 861 of file fl_text_input_handler_test.cc.

861  {
862  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
863  ::testing::NiceMock<flutter::testing::MockIMContext> context;
864  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
865 
866  g_autoptr(FlTextInputHandler) handler =
867  fl_text_input_handler_new(messenger, context, delegate);
868  EXPECT_NE(handler, nullptr);
869 
870  // set config
871  g_autoptr(FlValue) args = build_input_config({
872  .client_id = 1,
873  .enable_delta_model = true,
874  });
875  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
877  FL_METHOD_CODEC(codec), "TextInput.setClient", args, nullptr);
878 
879  g_autoptr(FlValue) null = fl_value_new_null();
880  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
881  ::testing::Eq<FlBinaryMessenger*>(messenger),
882  ::testing::A<FlBinaryMessengerResponseHandle*>(),
883  SuccessResponse(null), ::testing::A<GError**>()))
884  .WillOnce(::testing::Return(true));
885 
886  messenger.ReceiveMessage("flutter/textinput", set_client);
887 
888  // set editing state
889  g_autoptr(FlValue) state = build_editing_state({
890  .text = "Flutter",
891  .selection_base = 7,
892  .selection_extent = 7,
893  });
894  g_autoptr(GBytes) set_state = fl_method_codec_encode_method_call(
895  FL_METHOD_CODEC(codec), "TextInput.setEditingState", state, nullptr);
896 
897  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
898  ::testing::Eq<FlBinaryMessenger*>(messenger),
899  ::testing::_, SuccessResponse(null), ::testing::_))
900  .WillOnce(::testing::Return(true));
901 
902  messenger.ReceiveMessage("flutter/textinput", set_state);
903 
904  // update editing state with deltas
905  g_autoptr(FlValue) deltas = build_list({
906  fl_value_new_int(1), // client_id
907  build_map({{
908  "deltas",
909  build_list({
911  .old_text = "Flutter",
912  .delta_text = "Flutter",
913  .delta_start = 7,
914  .delta_end = 7,
915  .selection_base = 0,
916  .selection_extent = 0,
917  }),
918  }),
919  }}),
920  });
921 
922  EXPECT_CALL(messenger,
924  ::testing::Eq<FlBinaryMessenger*>(messenger),
925  ::testing::StrEq("flutter/textinput"),
926  MethodCall("TextInputClient.updateEditingStateWithDeltas",
927  FlValueEq(deltas)),
928  ::testing::_, ::testing::_, ::testing::_));
929 
930  send_key_event(handler, GDK_KEY_Home);
931 }

References args, build_editing_delta(), build_editing_state(), build_input_config(), build_list(), build_map(), fl_binary_messenger_send_on_channel(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [16/16]

TEST ( FlTextInputHandlerTest  ,
TextInputTypeNone   
)

Definition at line 818 of file fl_text_input_handler_test.cc.

818  {
819  ::testing::NiceMock<flutter::testing::MockBinaryMessenger> messenger;
820  ::testing::NiceMock<flutter::testing::MockIMContext> context;
821  ::testing::NiceMock<flutter::testing::MockTextInputViewDelegate> delegate;
822 
823  g_autoptr(FlTextInputHandler) handler =
824  fl_text_input_handler_new(messenger, context, delegate);
825  EXPECT_NE(handler, nullptr);
826 
827  g_autoptr(FlValue) args = build_input_config({
828  .client_id = 1,
829  .input_type = "TextInputType.none",
830  });
831  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
833  FL_METHOD_CODEC(codec), "TextInput.setClient", args, nullptr);
834 
835  g_autoptr(FlValue) null = fl_value_new_null();
836  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
837  ::testing::Eq<FlBinaryMessenger*>(messenger),
838  ::testing::A<FlBinaryMessengerResponseHandle*>(),
839  SuccessResponse(null), ::testing::A<GError**>()))
840  .WillOnce(::testing::Return(true));
841 
842  messenger.ReceiveMessage("flutter/textinput", set_client);
843 
844  EXPECT_CALL(context,
845  gtk_im_context_focus_in(::testing::Eq<GtkIMContext*>(context)))
846  .Times(0);
847  EXPECT_CALL(context,
848  gtk_im_context_focus_out(::testing::Eq<GtkIMContext*>(context)));
849 
850  EXPECT_CALL(messenger, fl_binary_messenger_send_response(
851  ::testing::Eq<FlBinaryMessenger*>(messenger),
852  ::testing::_, SuccessResponse(null), ::testing::_))
853  .WillOnce(::testing::Return(true));
854 
855  g_autoptr(GBytes) show = fl_method_codec_encode_method_call(
856  FL_METHOD_CODEC(codec), "TextInput.show", nullptr, nullptr);
857 
858  messenger.ReceiveMessage("flutter/textinput", show);
859 }

References args, build_input_config(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_handler_new(), fl_value_new_null(), set_client(), and show().

EditingDelta::delta_end
int delta_end
Definition: fl_text_input_handler_test.cc:159
build_list
static FlValue * build_list(std::vector< FlValue * > args)
Definition: fl_text_input_handler_test.cc:107
fl_json_method_codec_new
G_MODULE_EXPORT FlJsonMethodCodec * fl_json_method_codec_new()
Definition: fl_json_method_codec.cc:205
fl_method_codec_encode_method_call
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
Definition: fl_method_codec.cc:16
fl_key_event_new_from_gdk_event
FlKeyEvent * fl_key_event_new_from_gdk_event(GdkEvent *event)
Definition: fl_key_event.cc:53
InputConfig::enable_delta_model
gboolean enable_delta_model
Definition: fl_text_input_handler_test.cc:119
fl_text_input_view_delegate_translate_coordinates
void fl_text_input_view_delegate_translate_coordinates(FlTextInputViewDelegate *self, gint view_x, gint view_y, gint *window_x, gint *window_y)
Definition: fl_text_input_view_delegate.cc:14
fl_value_set_string_take
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650
set_client
static FlMethodResponse * set_client(FlTextInputHandler *self, FlValue *args)
Definition: fl_text_input_handler.cc:364
fl_value_new_list
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:349
EditingDelta::composing_extent
int composing_extent
Definition: fl_text_input_handler_test.cc:163
show
static FlMethodResponse * show(FlTextInputHandler *self)
Definition: fl_text_input_handler.cc:417
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
fl_value_new_null
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
fl_text_input_handler_new
FlTextInputHandler * fl_text_input_handler_new(FlBinaryMessenger *messenger, GtkIMContext *im_context, FlTextInputViewDelegate *view_delegate)
Definition: fl_text_input_handler.cc:747
InputConfig::client_id
int64_t client_id
Definition: fl_text_input_handler_test.cc:116
fl_method_response_get_result
G_MODULE_EXPORT FlValue * fl_method_response_get_result(FlMethodResponse *self, GError **error)
Definition: fl_method_response.cc:82
EditingDelta::delta_text
const gchar * delta_text
Definition: fl_text_input_handler_test.cc:157
EditingDelta::delta_start
int delta_start
Definition: fl_text_input_handler_test.cc:158
fl_value_new_int
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
EditingDelta::selection_extent
int selection_extent
Definition: fl_text_input_handler_test.cc:161
state
AtkStateType state
Definition: fl_accessible_node.cc:10
set_editable_size_and_transform
static FlMethodResponse * set_editable_size_and_transform(FlTextInputHandler *self, FlValue *args)
Definition: fl_text_input_handler.cc:518
build_map
static FlValue * build_map(std::map< const gchar *, FlValue * > args)
Definition: fl_text_input_handler_test.cc:99
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
fl_text_input_handler_filter_keypress
gboolean fl_text_input_handler_filter_keypress(FlTextInputHandler *self, FlKeyEvent *event)
Definition: fl_text_input_handler.cc:778
EditingDelta::old_text
const gchar * old_text
Definition: fl_text_input_handler_test.cc:156
end
glong glong end
Definition: fl_accessible_text_field.cc:40
set_marked_text_rect
static FlMethodResponse * set_marked_text_rect(FlTextInputHandler *self, FlValue *args)
Definition: fl_text_input_handler.cc:542
fl_value_append_take
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
fl_method_codec_decode_response
FlMethodResponse * fl_method_codec_decode_response(FlMethodCodec *self, GBytes *message, GError **error)
Definition: fl_method_codec.cc:62
fl_value_equal
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471
EditingDelta::composing_base
int composing_base
Definition: fl_text_input_handler_test.cc:162
MethodCall
::testing::Matcher< GBytes * > MethodCall(const std::string &name, ::testing::Matcher< FlValue * > args)
Definition: fl_text_input_handler_test.cc:94
height
const uint8_t uint32_t uint32_t * height
Definition: fl_pixel_buffer_texture_test.cc:39
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
MethodCallMatcher
Definition: fl_platform_handler_test.cc:31
send_key_event
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
Definition: fl_text_input_handler_test.cc:181
build_input_config
static FlValue * build_input_config(InputConfig config)
Definition: fl_text_input_handler_test.cc:122
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
build_editing_state
static FlValue * build_editing_state(EditingState state)
Definition: fl_text_input_handler_test.cc:143
InputConfig::input_type
const gchar * input_type
Definition: fl_text_input_handler_test.cc:117
InputConfig::input_action
const gchar * input_action
Definition: fl_text_input_handler_test.cc:118
fl_value_new_float
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition: fl_value.cc:269
fl_binary_messenger_send_response
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
Definition: fl_binary_messenger.cc:430
width
const uint8_t uint32_t * width
Definition: fl_pixel_buffer_texture_test.cc:38
build_editing_delta
static FlValue * build_editing_delta(EditingDelta delta)
Definition: fl_text_input_handler_test.cc:166
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
fl_binary_messenger_send_on_channel
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_binary_messenger.cc:443
fl_value_new_string
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
EditingDelta::selection_base
int selection_base
Definition: fl_text_input_handler_test.cc:160