Flutter Linux Embedder
fl_text_input_plugin_test.cc File Reference
#include <utility>
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
#include "flutter/shell/platform/linux/fl_text_input_plugin.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 (FlTextInputPlugin *plugin, gint keyval, gint state=0)
 
 TEST (FlTextInputPluginTest, MessageHandler)
 
 TEST (FlTextInputPluginTest, SetClient)
 
 TEST (FlTextInputPluginTest, Show)
 
 TEST (FlTextInputPluginTest, Hide)
 
 TEST (FlTextInputPluginTest, ClearClient)
 
 TEST (FlTextInputPluginTest, PerformAction)
 
 TEST (FlTextInputPluginTest, MultilineWithSendAction)
 
 TEST (FlTextInputPluginTest, MoveCursor)
 
 TEST (FlTextInputPluginTest, Select)
 
 TEST (FlTextInputPluginTest, Composing)
 
 TEST (FlTextInputPluginTest, SurroundingText)
 
 TEST (FlTextInputPluginTest, SetMarkedTextRect)
 
 TEST (FlTextInputPluginTest, TextInputTypeNone)
 
 TEST (FlTextInputPluginTest, TextEditingDelta)
 
 TEST (FlTextInputPluginTest, ComposingDelta)
 
 TEST (FlTextInputPluginTest, NonComposingDelta)
 

Function Documentation

◆ build_editing_delta()

static FlValue* build_editing_delta ( EditingDelta  delta)
static

Definition at line 166 of file fl_text_input_plugin_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_plugin_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_plugin_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_plugin_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_plugin_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_plugin_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_plugin_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_plugin_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_plugin_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 ( FlTextInputPlugin *  plugin,
gint  keyval,
gint  state = 0 
)
static

Definition at line 181 of file fl_text_input_plugin_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  FlKeyEvent* key_event = fl_key_event_new_from_gdk_event(gdk_event);
188  fl_text_input_plugin_filter_keypress(plugin, key_event);
189  fl_key_event_dispose(key_event);
190 }

References fl_key_event_dispose(), fl_key_event_new_from_gdk_event(), fl_text_input_plugin_filter_keypress(), and state.

Referenced by fl_key_embedder_responder_new(), and TEST().

◆ TEST() [1/16]

TEST ( FlTextInputPluginTest  ,
ClearClient   
)

Definition at line 277 of file fl_text_input_plugin_test.cc.

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

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

◆ TEST() [2/16]

TEST ( FlTextInputPluginTest  ,
Composing   
)

Definition at line 596 of file fl_text_input_plugin_test.cc.

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

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

◆ TEST() [3/16]

TEST ( FlTextInputPluginTest  ,
ComposingDelta   
)

Definition at line 934 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), and set_client().

◆ TEST() [4/16]

TEST ( FlTextInputPluginTest  ,
Hide   
)

Definition at line 252 of file fl_text_input_plugin_test.cc.

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

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

◆ TEST() [5/16]

TEST ( FlTextInputPluginTest  ,
MessageHandler   
)

Definition at line 192 of file fl_text_input_plugin_test.cc.

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

References fl_text_input_plugin_new().

◆ TEST() [6/16]

TEST ( FlTextInputPluginTest  ,
MoveCursor   
)

Definition at line 440 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [7/16]

TEST ( FlTextInputPluginTest  ,
MultilineWithSendAction   
)

Definition at line 376 of file fl_text_input_plugin_test.cc.

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

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_plugin_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 ( FlTextInputPluginTest  ,
NonComposingDelta   
)

Definition at line 1057 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), and set_client().

◆ TEST() [9/16]

TEST ( FlTextInputPluginTest  ,
PerformAction   
)

Definition at line 299 of file fl_text_input_plugin_test.cc.

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

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_plugin_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 ( FlTextInputPluginTest  ,
Select   
)

Definition at line 518 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [11/16]

TEST ( FlTextInputPluginTest  ,
SetClient   
)

Definition at line 204 of file fl_text_input_plugin_test.cc.

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

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

◆ TEST() [12/16]

TEST ( FlTextInputPluginTest  ,
SetMarkedTextRect   
)

Definition at line 736 of file fl_text_input_plugin_test.cc.

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

References build_list(), build_map(), fl_binary_messenger_send_response(), fl_json_method_codec_new(), fl_method_codec_encode_method_call(), fl_text_input_plugin_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 ( FlTextInputPluginTest  ,
Show   
)

Definition at line 227 of file fl_text_input_plugin_test.cc.

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

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

◆ TEST() [14/16]

TEST ( FlTextInputPluginTest  ,
SurroundingText   
)

Definition at line 666 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), set_client(), and state.

◆ TEST() [15/16]

TEST ( FlTextInputPluginTest  ,
TextEditingDelta   
)

Definition at line 862 of file fl_text_input_plugin_test.cc.

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

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_plugin_new(), fl_value_new_int(), fl_value_new_null(), MethodCall(), send_key_event(), set_client(), and state.

◆ TEST() [16/16]

TEST ( FlTextInputPluginTest  ,
TextInputTypeNone   
)

Definition at line 819 of file fl_text_input_plugin_test.cc.

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

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

EditingDelta::delta_end
int delta_end
Definition: fl_text_input_plugin_test.cc:159
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:7
InputConfig::enable_delta_model
gboolean enable_delta_model
Definition: fl_text_input_plugin_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
set_editable_size_and_transform
static FlMethodResponse * set_editable_size_and_transform(FlTextInputPlugin *self, FlValue *args)
Definition: fl_text_input_plugin.cc:518
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
fl_text_input_plugin_filter_keypress
gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin *self, FlKeyEvent *event)
Definition: fl_text_input_plugin.cc:776
MethodCall
::testing::Matcher< GBytes * > MethodCall(const std::string &name, ::testing::Matcher< FlValue * > args)
Definition: fl_text_input_plugin_test.cc:94
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_plugin_test.cc:163
set_marked_text_rect
static FlMethodResponse * set_marked_text_rect(FlTextInputPlugin *self, FlValue *args)
Definition: fl_text_input_plugin.cc:542
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
InputConfig::client_id
int64_t client_id
Definition: fl_text_input_plugin_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_plugin_test.cc:157
EditingDelta::delta_start
int delta_start
Definition: fl_text_input_plugin_test.cc:158
height
G_BEGIN_DECLS int height
Definition: fl_backing_store_provider.h:37
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_plugin_test.cc:161
_FlKeyEvent
Definition: fl_key_event.h:22
state
AtkStateType state
Definition: fl_accessible_node.cc:10
set_client
static FlMethodResponse * set_client(FlTextInputPlugin *self, FlValue *args)
Definition: fl_text_input_plugin.cc:364
show
static FlMethodResponse * show(FlTextInputPlugin *self)
Definition: fl_text_input_plugin.cc:417
build_editing_state
static FlValue * build_editing_state(EditingState state)
Definition: fl_text_input_plugin_test.cc:143
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
build_map
static FlValue * build_map(std::map< const gchar *, FlValue * > args)
Definition: fl_text_input_plugin_test.cc:99
EditingDelta::old_text
const gchar * old_text
Definition: fl_text_input_plugin_test.cc:156
build_input_config
static FlValue * build_input_config(InputConfig config)
Definition: fl_text_input_plugin_test.cc:122
build_list
static FlValue * build_list(std::vector< FlValue * > args)
Definition: fl_text_input_plugin_test.cc:107
end
glong glong end
Definition: fl_accessible_text_field.cc:40
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_plugin_test.cc:162
fl_key_event_dispose
void fl_key_event_dispose(FlKeyEvent *event)
Definition: fl_key_event.cc:32
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
MethodCallMatcher
Definition: fl_platform_plugin_test.cc:31
build_editing_delta
static FlValue * build_editing_delta(EditingDelta delta)
Definition: fl_text_input_plugin_test.cc:166
args
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: fl_event_channel.h:89
InputConfig::input_type
const gchar * input_type
Definition: fl_text_input_plugin_test.cc:117
send_key_event
static void send_key_event(FlTextInputPlugin *plugin, gint keyval, gint state=0)
Definition: fl_text_input_plugin_test.cc:181
InputConfig::input_action
const gchar * input_action
Definition: fl_text_input_plugin_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
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
fl_text_input_plugin_new
FlTextInputPlugin * fl_text_input_plugin_new(FlBinaryMessenger *messenger, GtkIMContext *im_context, FlTextInputViewDelegate *view_delegate)
Definition: fl_text_input_plugin.cc:745
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_plugin_test.cc:160