6 #include "gtest/gtest.h"
8 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
12 #include "flutter/shell/platform/linux/testing/mock_signal_handler.h"
18 g_autoptr(GBytes) bytes = g_bytes_new(data, data_length);
26 TEST(FlAccessibleTextFieldTest, SetValue) {
29 g_autoptr(FlAccessibleNode) node =
34 flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
36 flutter::testing::MockSignalHandler text_removed(node,
"text-remove");
38 EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(7));
39 EXPECT_SIGNAL(text_removed).Times(0);
46 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
47 flutter::testing::MockSignalHandler text_removed(node,
"text-remove");
49 EXPECT_SIGNAL(text_inserted).Times(0);
50 EXPECT_SIGNAL(text_removed).Times(0);
57 flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
59 flutter::testing::MockSignalHandler2<int, int> text_removed(node,
62 EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(6));
63 EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(7));
70 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
71 flutter::testing::MockSignalHandler2<int, int> text_removed(node,
74 EXPECT_SIGNAL(text_inserted).Times(0);
75 EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(6));
84 TEST(FlAccessibleTextFieldTest, SetTextSelection) {
87 g_autoptr(FlAccessibleNode) node =
92 flutter::testing::MockSignalHandler text_selection_changed(
93 node,
"text-selection-changed");
94 flutter::testing::MockSignalHandler1<int> text_caret_moved(
95 node,
"text-caret-moved");
97 EXPECT_SIGNAL(text_selection_changed);
98 EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(3));
105 flutter::testing::MockSignalHandler text_selection_changed(
106 node,
"text-selection-changed");
107 flutter::testing::MockSignalHandler text_caret_moved(node,
110 EXPECT_SIGNAL(text_selection_changed);
111 EXPECT_SIGNAL(text_caret_moved).Times(0);
118 flutter::testing::MockSignalHandler text_selection_changed(
119 node,
"text-selection-changed");
120 flutter::testing::MockSignalHandler text_caret_moved(node,
123 EXPECT_SIGNAL(text_selection_changed).Times(0);
124 EXPECT_SIGNAL(text_caret_moved).Times(0);
131 flutter::testing::MockSignalHandler text_selection_changed(
132 node,
"text-selection-changed");
133 flutter::testing::MockSignalHandler1<int> text_caret_moved(
134 node,
"text-caret-moved");
136 EXPECT_SIGNAL(text_selection_changed).Times(0);
137 EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(4));
145 TEST(FlAccessibleTextFieldTest, PerformAction) {
146 g_autoptr(GPtrArray) action_datas = g_ptr_array_new_with_free_func(
152 g_autoptr(GError)
error =
nullptr;
154 EXPECT_EQ(
error,
nullptr);
158 ([&action_datas](
auto engine,
159 const FlutterSendSemanticsActionInfo* info) {
160 g_ptr_array_add(action_datas,
165 g_autoptr(FlAccessibleNode) node =
168 node,
static_cast<FlutterSemanticsAction
>(
169 kFlutterSemanticsActionMoveCursorForwardByCharacter |
170 kFlutterSemanticsActionMoveCursorBackwardByCharacter |
171 kFlutterSemanticsActionMoveCursorForwardByWord |
172 kFlutterSemanticsActionMoveCursorBackwardByWord));
176 for (
int i = 0;
i < 4; ++
i) {
177 atk_action_do_action(ATK_ACTION(node),
i);
179 FlValue* data =
static_cast<FlValue*
>(g_ptr_array_index(action_datas,
i));
180 EXPECT_NE(data,
nullptr);
186 TEST(FlAccessibleTextFieldTest, GetCharacterCount) {
189 g_autoptr(FlAccessibleNode) node =
192 EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 0);
196 EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 8);
200 TEST(FlAccessibleTextFieldTest, GetText) {
203 g_autoptr(FlAccessibleNode) node =
206 g_autofree gchar* empty = atk_text_get_text(ATK_TEXT(node), 0, -1);
207 EXPECT_STREQ(empty,
"");
209 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
210 EXPECT_SIGNAL(text_inserted).Times(1);
214 g_autofree gchar*
flutter = atk_text_get_text(ATK_TEXT(node), 0, -1);
215 EXPECT_STREQ(
flutter,
"Flutter!");
217 g_autofree gchar* tt = atk_text_get_text(ATK_TEXT(node), 3, 5);
218 EXPECT_STREQ(tt,
"tt");
222 TEST(FlAccessibleTextFieldTest, GetCaretOffset) {
225 g_autoptr(FlAccessibleNode) node =
228 EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), -1);
232 EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), 2);
236 TEST(FlAccessibleTextFieldTest, SetCaretOffset) {
243 g_autoptr(GError)
error =
nullptr;
245 EXPECT_EQ(
error,
nullptr);
249 ([&base, &extent](
auto engine,
250 const FlutterSendSemanticsActionInfo* info) {
251 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
260 g_autoptr(FlAccessibleNode) node =
263 EXPECT_TRUE(atk_text_set_caret_offset(ATK_TEXT(node), 3));
265 EXPECT_EQ(extent, 3);
269 TEST(FlAccessibleTextFieldTest, GetNSelections) {
272 g_autoptr(FlAccessibleNode) node =
275 EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 0);
279 EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 1);
283 TEST(FlAccessibleTextFieldTest, GetSelection) {
286 g_autoptr(FlAccessibleNode) node =
289 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0,
nullptr,
nullptr),
296 g_autofree gchar* selection =
297 atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end);
298 EXPECT_STREQ(selection,
"utt");
304 g_autofree gchar* reverse =
305 atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end);
306 EXPECT_STREQ(reverse,
"utt");
312 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end),
nullptr);
315 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 1, &
start, &
end),
nullptr);
319 TEST(FlAccessibleTextFieldTest, AddSelection) {
326 g_autoptr(GError)
error =
nullptr;
328 EXPECT_EQ(
error,
nullptr);
332 ([&base, &extent](
auto engine,
333 const FlutterSendSemanticsActionInfo* info) {
334 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
343 g_autoptr(FlAccessibleNode) node =
346 EXPECT_TRUE(atk_text_add_selection(ATK_TEXT(node), 2, 4));
348 EXPECT_EQ(extent, 4);
353 EXPECT_FALSE(atk_text_add_selection(ATK_TEXT(node), 6, 7));
355 EXPECT_EQ(extent, 4);
359 TEST(FlAccessibleTextFieldTest, RemoveSelection) {
366 g_autoptr(GError)
error =
nullptr;
368 EXPECT_EQ(
error,
nullptr);
372 ([&base, &extent](
auto engine,
373 const FlutterSendSemanticsActionInfo* info) {
374 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
383 g_autoptr(FlAccessibleNode) node =
387 EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 0));
389 EXPECT_EQ(extent, -1);
394 EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 1));
396 EXPECT_EQ(extent, -1);
399 EXPECT_TRUE(atk_text_remove_selection(ATK_TEXT(node), 0));
401 EXPECT_EQ(extent, 4);
405 TEST(FlAccessibleTextFieldTest, SetSelection) {
412 g_autoptr(GError)
error =
nullptr;
414 EXPECT_EQ(
error,
nullptr);
418 ([&base, &extent](
auto engine,
419 const FlutterSendSemanticsActionInfo* info) {
420 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
429 g_autoptr(FlAccessibleNode) node =
433 EXPECT_FALSE(atk_text_set_selection(ATK_TEXT(node), 1, 2, 4));
435 EXPECT_EQ(extent, -1);
437 EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 2, 4));
439 EXPECT_EQ(extent, 4);
441 EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 5, 1));
443 EXPECT_EQ(extent, 1);
447 TEST(FlAccessibleTextFieldTest, SetTextContents) {
448 g_autofree gchar* text =
nullptr;
453 g_autoptr(GError)
error =
nullptr;
455 EXPECT_EQ(
error,
nullptr);
459 ([&text](
auto engine,
const FlutterSendSemanticsActionInfo* info) {
460 EXPECT_EQ(info->action, kFlutterSemanticsActionSetText);
468 g_autoptr(FlAccessibleNode) node =
471 atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(node),
"Flutter");
472 EXPECT_STREQ(text,
"Flutter");
476 TEST(FlAccessibleTextFieldTest, InsertDeleteText) {
477 g_autofree gchar* text =
nullptr;
484 g_autoptr(GError)
error =
nullptr;
486 EXPECT_EQ(
error,
nullptr);
490 ([&text, &base, &extent](
auto engine,
491 const FlutterSendSemanticsActionInfo* info) {
492 EXPECT_THAT(info->action,
493 ::testing::AnyOf(kFlutterSemanticsActionSetText,
494 kFlutterSemanticsActionSetSelection));
495 if (info->action == kFlutterSemanticsActionSetText) {
511 g_autoptr(FlAccessibleNode) node =
516 atk_editable_text_insert_text(ATK_EDITABLE_TEXT(node),
"utt", 3, &pos);
518 EXPECT_STREQ(text,
"Flutter");
519 EXPECT_EQ(base, pos);
520 EXPECT_EQ(extent, pos);
522 atk_editable_text_delete_text(ATK_EDITABLE_TEXT(node), 2, 5);
523 EXPECT_STREQ(text,
"Fler");
525 EXPECT_EQ(extent, 2);
529 TEST(FlAccessibleTextFieldTest, CopyCutPasteText) {
532 FlutterSemanticsAction act = kFlutterSemanticsActionCustomAction;
537 g_autoptr(GError)
error =
nullptr;
539 EXPECT_EQ(
error,
nullptr);
543 ([&act, &base, &extent](
auto engine,
544 const FlutterSendSemanticsActionInfo* info) {
545 EXPECT_THAT(info->action,
546 ::testing::AnyOf(kFlutterSemanticsActionCut,
547 kFlutterSemanticsActionCopy,
548 kFlutterSemanticsActionPaste,
549 kFlutterSemanticsActionSetSelection));
551 if (info->action == kFlutterSemanticsActionSetSelection) {
561 g_autoptr(FlAccessibleNode) node =
564 atk_editable_text_copy_text(ATK_EDITABLE_TEXT(node), 2, 5);
566 EXPECT_EQ(extent, 5);
567 EXPECT_EQ(act, kFlutterSemanticsActionCopy);
569 atk_editable_text_cut_text(ATK_EDITABLE_TEXT(node), 1, 4);
571 EXPECT_EQ(extent, 4);
572 EXPECT_EQ(act, kFlutterSemanticsActionCut);
574 atk_editable_text_paste_text(ATK_EDITABLE_TEXT(node), 3);
576 EXPECT_EQ(extent, 3);
577 EXPECT_EQ(act, kFlutterSemanticsActionPaste);
580 TEST(FlAccessibleTextFieldTest, TextBoundary) {
583 g_autoptr(FlAccessibleNode) node =
587 "Lorem ipsum.\nDolor sit amet. Praesent commodo?"
588 "\n\nPraesent et felis dui.");
591 gint start_offset = -1, end_offset = -1;
592 g_autofree gchar* lorem_char = atk_text_get_string_at_offset(
593 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
594 EXPECT_STREQ(lorem_char,
"L");
595 EXPECT_EQ(start_offset, 0);
596 EXPECT_EQ(end_offset, 1);
598 g_autofree gchar* lorem_word = atk_text_get_string_at_offset(
599 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
600 EXPECT_STREQ(lorem_word,
"Lorem");
601 EXPECT_EQ(start_offset, 0);
602 EXPECT_EQ(end_offset, 5);
604 g_autofree gchar* lorem_sentence = atk_text_get_string_at_offset(
605 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
607 EXPECT_STREQ(lorem_sentence,
"Lorem ipsum.");
608 EXPECT_EQ(start_offset, 0);
609 EXPECT_EQ(end_offset, 12);
611 g_autofree gchar* lorem_line = atk_text_get_string_at_offset(
612 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_LINE, &start_offset, &end_offset);
613 EXPECT_STREQ(lorem_line,
"Lorem ipsum.");
614 EXPECT_EQ(start_offset, 0);
615 EXPECT_EQ(end_offset, 12);
617 g_autofree gchar* lorem_paragraph = atk_text_get_string_at_offset(
618 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
620 EXPECT_STREQ(lorem_paragraph,
621 "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
622 EXPECT_EQ(start_offset, 0);
623 EXPECT_EQ(end_offset, 46);
626 g_autofree gchar* praesent_char = atk_text_get_string_at_offset(
627 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
629 EXPECT_STREQ(praesent_char,
"e");
630 EXPECT_EQ(start_offset, 32);
631 EXPECT_EQ(end_offset, 33);
633 g_autofree gchar* praesent_word = atk_text_get_string_at_offset(
634 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_WORD, &start_offset,
636 EXPECT_STREQ(praesent_word,
"Praesent");
637 EXPECT_EQ(start_offset, 29);
638 EXPECT_EQ(end_offset, 37);
640 g_autofree gchar* praesent_sentence = atk_text_get_string_at_offset(
641 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
643 EXPECT_STREQ(praesent_sentence,
"Praesent commodo?");
644 EXPECT_EQ(start_offset, 29);
645 EXPECT_EQ(end_offset, 46);
647 g_autofree gchar* praesent_line = atk_text_get_string_at_offset(
648 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_LINE, &start_offset,
650 EXPECT_STREQ(praesent_line,
"Dolor sit amet. Praesent commodo?");
651 EXPECT_EQ(start_offset, 13);
652 EXPECT_EQ(end_offset, 46);
654 g_autofree gchar* praesent_paragraph = atk_text_get_string_at_offset(
655 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
657 EXPECT_STREQ(praesent_paragraph,
658 "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
659 EXPECT_EQ(start_offset, 0);
660 EXPECT_EQ(end_offset, 46);
663 g_autofree gchar* felis_char = atk_text_get_string_at_offset(
664 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
666 EXPECT_STREQ(felis_char,
"s");
667 EXPECT_EQ(start_offset, 64);
668 EXPECT_EQ(end_offset, 65);
670 g_autofree gchar* felis_word = atk_text_get_string_at_offset(
671 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_WORD, &start_offset,
673 EXPECT_STREQ(felis_word,
"felis");
674 EXPECT_EQ(start_offset, 60);
675 EXPECT_EQ(end_offset, 65);
677 g_autofree gchar* felis_sentence = atk_text_get_string_at_offset(
678 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
680 EXPECT_STREQ(felis_sentence,
"Praesent et felis dui.");
681 EXPECT_EQ(start_offset, 48);
682 EXPECT_EQ(end_offset, 70);
684 g_autofree gchar* felis_line = atk_text_get_string_at_offset(
685 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_LINE, &start_offset,
687 EXPECT_STREQ(felis_line,
"Praesent et felis dui.");
688 EXPECT_EQ(start_offset, 48);
689 EXPECT_EQ(end_offset, 70);
691 g_autofree gchar* felis_paragraph = atk_text_get_string_at_offset(
692 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
694 EXPECT_STREQ(felis_paragraph,
"\nPraesent et felis dui.");
695 EXPECT_EQ(start_offset, 47);
696 EXPECT_EQ(end_offset, 70);
void fl_accessible_node_set_text_selection(FlAccessibleNode *self, gint base, gint extent)
void fl_accessible_node_set_actions(FlAccessibleNode *self, FlutterSemanticsAction actions)
void fl_accessible_node_set_value(FlAccessibleNode *self, const gchar *value)
FlAccessibleNode * fl_accessible_text_field_new(FlEngine *engine, FlutterViewId view_id, int32_t id)
static FlValue * decode_semantic_data(const uint8_t *data, size_t data_length)
TEST(FlAccessibleTextFieldTest, SetValue)
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
gboolean fl_engine_start(FlEngine *self, GError **error)
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT FlStandardMessageCodec * fl_standard_message_codec_new()
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
typedefG_BEGIN_DECLS struct _FlValue FlValue