Flutter Engine
The Flutter Engine
Classes | Functions
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}
static FlValue * build_map(std::map< const gchar *, FlValue * > args)
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262

◆ 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}
AtkStateType state

◆ 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({
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}
static FlValue * build_list(std::vector< FlValue * > args)
const gchar * input_action

◆ 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}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:349
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42

◆ 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}
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650

◆ 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}
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471

◆ 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}
G_MODULE_EXPORT FlJsonMethodCodec * fl_json_method_codec_new()
FlMethodResponse * fl_method_codec_decode_response(FlMethodCodec *self, GBytes *message, GError **error)
G_MODULE_EXPORT FlValue * fl_method_response_get_result(FlMethodResponse *self, GError **error)
GAsyncResult * result
static CStringUniquePtr PrintToString(const char *format,...)
Definition: uri.cc:41

◆ 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}
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32

◆ printTo()

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

Definition at line 22 of file fl_text_input_plugin_test.cc.

22 {
24 fl_method_response_get_result(response, nullptr));
25}

◆ 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;
190}
void fl_key_event_dispose(FlKeyEvent *event)
Definition: fl_key_event.cc:32
FlKeyEvent * fl_key_event_new_from_gdk_event(GdkEvent *event)
Definition: fl_key_event.cc:7
gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin *self, FlKeyEvent *event)
FlutterKeyEvent key_event

◆ 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();
294 FL_METHOD_CODEC(codec), "TextInput.clearClient", nullptr, nullptr);
295
296 messenger.ReceiveMessage("flutter/textinput", message);
297}
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(FlBinaryMessenger *self, FlBinaryMessengerResponseHandle *response_handle, GBytes *response, GError **error)
GBytes * fl_method_codec_encode_method_call(FlMethodCodec *self, const gchar *name, FlValue *args, GError **error)
FlTextInputPlugin * fl_text_input_plugin_new(FlBinaryMessenger *messenger, GtkIMContext *im_context, FlTextInputViewDelegate *view_delegate)
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
Win32Message message

◆ 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}
G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(FlBinaryMessenger *self, const gchar *channel, GBytes *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static FlValue * build_editing_state(EditingState state)
::testing::Matcher< GBytes * > MethodCall(const std::string &name, ::testing::Matcher< FlValue * > args)

◆ 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}
glong glong end
static FlMethodResponse * set_client(FlTextInputPlugin *self, FlValue *args)
static FlValue * build_input_config(InputConfig config)
static FlValue * build_editing_delta(EditingDelta delta)
Definition: update.py:1

◆ 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();
272 FL_METHOD_CODEC(codec), "TextInput.hide", nullptr, nullptr);
273
274 messenger.ReceiveMessage("flutter/textinput", message);
275}

◆ 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}
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678

◆ 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}
static void send_key_event(FlTextInputPlugin *plugin, gint keyval, gint state=0)

◆ 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}

◆ 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();
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}

◆ 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}

◆ 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}

◆ 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();
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}

◆ 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({
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}
static FlMethodResponse * set_marked_text_rect(FlTextInputPlugin *self, FlValue *args)
static FlMethodResponse * set_editable_size_and_transform(FlTextInputPlugin *self, FlValue *args)
void fl_text_input_view_delegate_translate_coordinates(FlTextInputViewDelegate *self, gint view_x, gint view_y, gint *window_x, gint *window_y)
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition: fl_value.cc:269
double y
double x
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
int32_t height
int32_t 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();
247 FL_METHOD_CODEC(codec), "TextInput.show", nullptr, nullptr);
248
249 messenger.ReceiveMessage("flutter/textinput", message);
250}

◆ 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}

◆ 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}

◆ 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}
static FlMethodResponse * show(FlTextInputPlugin *self)