6 #include "flutter/shell/platform/linux/testing/linux_test.h"
7 #include "gtest/gtest.h"
9 #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
13 #include "flutter/shell/platform/linux/testing/mock_signal_handler.h"
19 g_autoptr(GBytes) bytes = g_bytes_new(data, data_length);
35 flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
37 flutter::testing::MockSignalHandler text_removed(node,
"text-remove");
39 EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(7));
40 EXPECT_SIGNAL(text_removed).Times(0);
47 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
48 flutter::testing::MockSignalHandler text_removed(node,
"text-remove");
50 EXPECT_SIGNAL(text_inserted).Times(0);
51 EXPECT_SIGNAL(text_removed).Times(0);
58 flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
60 flutter::testing::MockSignalHandler2<int, int> text_removed(node,
63 EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(6));
64 EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(7));
71 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
72 flutter::testing::MockSignalHandler2<int, int> text_removed(node,
75 EXPECT_SIGNAL(text_inserted).Times(0);
76 EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(6));
91 flutter::testing::MockSignalHandler text_selection_changed(
92 node,
"text-selection-changed");
93 flutter::testing::MockSignalHandler1<int> text_caret_moved(
94 node,
"text-caret-moved");
96 EXPECT_SIGNAL(text_selection_changed);
97 EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(3));
104 flutter::testing::MockSignalHandler text_selection_changed(
105 node,
"text-selection-changed");
106 flutter::testing::MockSignalHandler text_caret_moved(node,
109 EXPECT_SIGNAL(text_selection_changed);
110 EXPECT_SIGNAL(text_caret_moved).Times(0);
117 flutter::testing::MockSignalHandler text_selection_changed(
118 node,
"text-selection-changed");
119 flutter::testing::MockSignalHandler text_caret_moved(node,
122 EXPECT_SIGNAL(text_selection_changed).Times(0);
123 EXPECT_SIGNAL(text_caret_moved).Times(0);
130 flutter::testing::MockSignalHandler text_selection_changed(
131 node,
"text-selection-changed");
132 flutter::testing::MockSignalHandler1<int> text_caret_moved(
133 node,
"text-caret-moved");
135 EXPECT_SIGNAL(text_selection_changed).Times(0);
136 EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(4));
145 g_autoptr(GPtrArray) action_datas = g_ptr_array_new_with_free_func(
152 ([&action_datas](
auto engine,
153 const FlutterSendSemanticsActionInfo* info) {
154 g_ptr_array_add(action_datas,
162 node,
static_cast<FlutterSemanticsAction
>(
163 kFlutterSemanticsActionMoveCursorForwardByCharacter |
164 kFlutterSemanticsActionMoveCursorBackwardByCharacter |
165 kFlutterSemanticsActionMoveCursorForwardByWord |
166 kFlutterSemanticsActionMoveCursorBackwardByWord));
170 for (
int i = 0;
i < 4; ++
i) {
171 atk_action_do_action(ATK_ACTION(node),
i);
173 FlValue* data =
static_cast<FlValue*
>(g_ptr_array_index(action_datas,
i));
174 EXPECT_NE(data,
nullptr);
184 EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 0);
188 EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 8);
196 g_autofree gchar* empty = atk_text_get_text(ATK_TEXT(node), 0, -1);
197 EXPECT_STREQ(empty,
"");
199 flutter::testing::MockSignalHandler text_inserted(node,
"text-insert");
200 EXPECT_SIGNAL(text_inserted).Times(1);
204 g_autofree gchar*
flutter = atk_text_get_text(ATK_TEXT(node), 0, -1);
205 EXPECT_STREQ(
flutter,
"Flutter!");
207 g_autofree gchar* tt = atk_text_get_text(ATK_TEXT(node), 3, 5);
208 EXPECT_STREQ(tt,
"tt");
219 g_autofree gchar* beyond = atk_text_get_text(ATK_TEXT(node), 100, -1);
220 EXPECT_STREQ(beyond,
"");
223 g_autofree gchar* end_beyond = atk_text_get_text(ATK_TEXT(node), 2, 100);
224 EXPECT_STREQ(end_beyond,
"llo");
227 g_autofree gchar* both_beyond = atk_text_get_text(ATK_TEXT(node), 50, 100);
228 EXPECT_STREQ(both_beyond,
"");
232 g_autofree gchar* empty_beyond = atk_text_get_text(ATK_TEXT(node), 5, 10);
233 EXPECT_STREQ(empty_beyond,
"");
241 EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), -1);
245 EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), 2);
257 ([&base, &extent](
auto engine,
258 const FlutterSendSemanticsActionInfo* info) {
259 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
271 EXPECT_TRUE(atk_text_set_caret_offset(ATK_TEXT(node), 3));
273 EXPECT_EQ(extent, 3);
281 EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 0);
285 EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 1);
293 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0,
nullptr,
nullptr),
300 g_autofree gchar* selection =
301 atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end);
302 EXPECT_STREQ(selection,
"utt");
308 g_autofree gchar* reverse =
309 atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end);
310 EXPECT_STREQ(reverse,
"utt");
316 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0, &
start, &
end),
nullptr);
319 EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 1, &
start, &
end),
nullptr);
331 ([&base, &extent](
auto engine,
332 const FlutterSendSemanticsActionInfo* info) {
333 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
345 EXPECT_TRUE(atk_text_add_selection(ATK_TEXT(node), 2, 4));
347 EXPECT_EQ(extent, 4);
352 EXPECT_FALSE(atk_text_add_selection(ATK_TEXT(node), 6, 7));
354 EXPECT_EQ(extent, 4);
366 ([&base, &extent](
auto engine,
367 const FlutterSendSemanticsActionInfo* info) {
368 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
381 EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 0));
383 EXPECT_EQ(extent, -1);
388 EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 1));
390 EXPECT_EQ(extent, -1);
393 EXPECT_TRUE(atk_text_remove_selection(ATK_TEXT(node), 0));
395 EXPECT_EQ(extent, 4);
407 ([&base, &extent](
auto engine,
408 const FlutterSendSemanticsActionInfo* info) {
409 EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
422 EXPECT_FALSE(atk_text_set_selection(ATK_TEXT(node), 1, 2, 4));
424 EXPECT_EQ(extent, -1);
426 EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 2, 4));
428 EXPECT_EQ(extent, 4);
430 EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 5, 1));
432 EXPECT_EQ(extent, 1);
437 g_autofree gchar* text =
nullptr;
443 ([&text](
auto engine,
const FlutterSendSemanticsActionInfo* info) {
444 EXPECT_EQ(info->action, kFlutterSemanticsActionSetText);
455 atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(node),
"Flutter");
456 EXPECT_STREQ(text,
"Flutter");
461 g_autofree gchar* text =
nullptr;
469 ([&text, &base, &extent](
auto engine,
470 const FlutterSendSemanticsActionInfo* info) {
471 EXPECT_THAT(info->action,
472 ::testing::AnyOf(kFlutterSemanticsActionSetText,
473 kFlutterSemanticsActionSetSelection));
474 if (info->action == kFlutterSemanticsActionSetText) {
495 atk_editable_text_insert_text(ATK_EDITABLE_TEXT(node),
"utt", 3, &pos);
497 EXPECT_STREQ(text,
"Flutter");
498 EXPECT_EQ(base, pos);
499 EXPECT_EQ(extent, pos);
501 atk_editable_text_delete_text(ATK_EDITABLE_TEXT(node), 2, 5);
502 EXPECT_STREQ(text,
"Fler");
504 EXPECT_EQ(extent, 2);
511 FlutterSemanticsAction act = kFlutterSemanticsActionCustomAction;
517 ([&act, &base, &extent](
auto engine,
518 const FlutterSendSemanticsActionInfo* info) {
519 EXPECT_THAT(info->action,
520 ::testing::AnyOf(kFlutterSemanticsActionCut,
521 kFlutterSemanticsActionCopy,
522 kFlutterSemanticsActionPaste,
523 kFlutterSemanticsActionSetSelection));
525 if (info->action == kFlutterSemanticsActionSetSelection) {
538 atk_editable_text_copy_text(ATK_EDITABLE_TEXT(node), 2, 5);
540 EXPECT_EQ(extent, 5);
541 EXPECT_EQ(act, kFlutterSemanticsActionCopy);
543 atk_editable_text_cut_text(ATK_EDITABLE_TEXT(node), 1, 4);
545 EXPECT_EQ(extent, 4);
546 EXPECT_EQ(act, kFlutterSemanticsActionCut);
548 atk_editable_text_paste_text(ATK_EDITABLE_TEXT(node), 3);
550 EXPECT_EQ(extent, 3);
551 EXPECT_EQ(act, kFlutterSemanticsActionPaste);
559 "Lorem ipsum.\nDolor sit amet. Praesent commodo?"
560 "\n\nPraesent et felis dui.");
563 gint start_offset = -1, end_offset = -1;
564 g_autofree gchar* lorem_char = atk_text_get_string_at_offset(
565 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
566 EXPECT_STREQ(lorem_char,
"L");
567 EXPECT_EQ(start_offset, 0);
568 EXPECT_EQ(end_offset, 1);
570 g_autofree gchar* lorem_word = atk_text_get_string_at_offset(
571 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
572 EXPECT_STREQ(lorem_word,
"Lorem");
573 EXPECT_EQ(start_offset, 0);
574 EXPECT_EQ(end_offset, 5);
576 g_autofree gchar* lorem_sentence = atk_text_get_string_at_offset(
577 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
579 EXPECT_STREQ(lorem_sentence,
"Lorem ipsum.");
580 EXPECT_EQ(start_offset, 0);
581 EXPECT_EQ(end_offset, 12);
583 g_autofree gchar* lorem_line = atk_text_get_string_at_offset(
584 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_LINE, &start_offset, &end_offset);
585 EXPECT_STREQ(lorem_line,
"Lorem ipsum.");
586 EXPECT_EQ(start_offset, 0);
587 EXPECT_EQ(end_offset, 12);
589 g_autofree gchar* lorem_paragraph = atk_text_get_string_at_offset(
590 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
592 EXPECT_STREQ(lorem_paragraph,
593 "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
594 EXPECT_EQ(start_offset, 0);
595 EXPECT_EQ(end_offset, 46);
598 g_autofree gchar* praesent_char = atk_text_get_string_at_offset(
599 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
601 EXPECT_STREQ(praesent_char,
"e");
602 EXPECT_EQ(start_offset, 32);
603 EXPECT_EQ(end_offset, 33);
605 g_autofree gchar* praesent_word = atk_text_get_string_at_offset(
606 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_WORD, &start_offset,
608 EXPECT_STREQ(praesent_word,
"Praesent");
609 EXPECT_EQ(start_offset, 29);
610 EXPECT_EQ(end_offset, 37);
612 g_autofree gchar* praesent_sentence = atk_text_get_string_at_offset(
613 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
615 EXPECT_STREQ(praesent_sentence,
"Praesent commodo?");
616 EXPECT_EQ(start_offset, 29);
617 EXPECT_EQ(end_offset, 46);
619 g_autofree gchar* praesent_line = atk_text_get_string_at_offset(
620 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_LINE, &start_offset,
622 EXPECT_STREQ(praesent_line,
"Dolor sit amet. Praesent commodo?");
623 EXPECT_EQ(start_offset, 13);
624 EXPECT_EQ(end_offset, 46);
626 g_autofree gchar* praesent_paragraph = atk_text_get_string_at_offset(
627 ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
629 EXPECT_STREQ(praesent_paragraph,
630 "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
631 EXPECT_EQ(start_offset, 0);
632 EXPECT_EQ(end_offset, 46);
635 g_autofree gchar* felis_char = atk_text_get_string_at_offset(
636 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
638 EXPECT_STREQ(felis_char,
"s");
639 EXPECT_EQ(start_offset, 64);
640 EXPECT_EQ(end_offset, 65);
642 g_autofree gchar* felis_word = atk_text_get_string_at_offset(
643 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_WORD, &start_offset,
645 EXPECT_STREQ(felis_word,
"felis");
646 EXPECT_EQ(start_offset, 60);
647 EXPECT_EQ(end_offset, 65);
649 g_autofree gchar* felis_sentence = atk_text_get_string_at_offset(
650 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
652 EXPECT_STREQ(felis_sentence,
"Praesent et felis dui.");
653 EXPECT_EQ(start_offset, 48);
654 EXPECT_EQ(end_offset, 70);
656 g_autofree gchar* felis_line = atk_text_get_string_at_offset(
657 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_LINE, &start_offset,
659 EXPECT_STREQ(felis_line,
"Praesent et felis dui.");
660 EXPECT_EQ(start_offset, 48);
661 EXPECT_EQ(end_offset, 70);
663 g_autofree gchar* felis_paragraph = atk_text_get_string_at_offset(
664 ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
666 EXPECT_STREQ(felis_paragraph,
"\nPraesent et felis dui.");
667 EXPECT_EQ(start_offset, 47);
668 EXPECT_EQ(end_offset, 70);
680 gint start_offset = -1, end_offset = -1;
681 g_autofree gchar* char_result = atk_text_get_string_at_offset(
682 ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
684 EXPECT_NE(char_result,
nullptr);
685 EXPECT_GE(start_offset, 0);
686 EXPECT_LE(end_offset, 5);
688 g_autofree gchar* word_result = atk_text_get_string_at_offset(
689 ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_WORD, &start_offset,
691 EXPECT_NE(word_result,
nullptr);
692 EXPECT_GE(start_offset, 0);
693 EXPECT_LE(end_offset, 5);
695 g_autofree gchar* sentence_result = atk_text_get_string_at_offset(
696 ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
698 EXPECT_NE(sentence_result,
nullptr);
699 EXPECT_GE(start_offset, 0);
700 EXPECT_LE(end_offset, 5);
711 gint start_offset = -1, end_offset = -1;
712 g_autofree gchar* char_result = atk_text_get_string_at_offset(
713 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
714 EXPECT_NE(char_result,
nullptr);
715 EXPECT_EQ(start_offset, 0);
716 EXPECT_EQ(end_offset, 1);
717 EXPECT_STREQ(char_result,
"H");
719 g_autofree gchar* word_result = atk_text_get_string_at_offset(
720 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
721 EXPECT_NE(word_result,
nullptr);
722 EXPECT_EQ(start_offset, 0);
723 EXPECT_EQ(end_offset, 5);
724 EXPECT_STREQ(word_result,
"Hello");
733 gint start_offset = -1, end_offset = -1;
734 g_autofree gchar* char_result = atk_text_get_string_at_offset(
735 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
736 EXPECT_NE(char_result,
nullptr);
737 EXPECT_EQ(start_offset, 0);
738 EXPECT_STREQ(char_result,
"");
740 g_autofree gchar* word_result = atk_text_get_string_at_offset(
741 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
742 EXPECT_NE(word_result,
nullptr);
743 EXPECT_EQ(start_offset, 0);
744 EXPECT_STREQ(word_result,
"");
755 gint char_count = atk_text_get_character_count(ATK_TEXT(node));
756 EXPECT_EQ(char_count, 11);
758 gint start_offset = -1, end_offset = -1;
759 g_autofree gchar* char_result = atk_text_get_string_at_offset(
760 ATK_TEXT(node), char_count, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
762 EXPECT_NE(char_result,
nullptr);
763 EXPECT_GE(start_offset, 0);
764 EXPECT_LE(end_offset, char_count);
766 g_autofree gchar* word_result = atk_text_get_string_at_offset(
767 ATK_TEXT(node), char_count, ATK_TEXT_GRANULARITY_WORD, &start_offset,
769 EXPECT_NE(word_result,
nullptr);
770 EXPECT_GE(start_offset, 0);
771 EXPECT_LE(end_offset, char_count);
786 EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 10);
789 gint start_offset = -1, end_offset = -1;
790 g_autofree gchar* line0 = atk_text_get_string_at_offset(
791 ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_LINE, &start_offset, &end_offset);
792 EXPECT_STREQ(line0,
"Café");
793 EXPECT_EQ(start_offset, 0);
794 EXPECT_EQ(end_offset, 4);
799 g_autofree gchar* line1 = atk_text_get_string_at_offset(
800 ATK_TEXT(node), 6, ATK_TEXT_GRANULARITY_LINE, &start_offset, &end_offset);
801 EXPECT_STREQ(line1,
"Münch");
802 EXPECT_EQ(start_offset, 5);
803 EXPECT_EQ(end_offset, 10);
806 g_autofree gchar* paragraph = atk_text_get_string_at_offset(
807 ATK_TEXT(node), 6, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
809 EXPECT_STREQ(paragraph,
"Café\nMünch");
810 EXPECT_EQ(start_offset, 0);
811 EXPECT_EQ(end_offset, 10);
g_autoptr(FlEngine) engine
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)
TEST_F(FlAccessibleTextFieldTest, SetValue)
static FlValue * decode_semantic_data(const uint8_t *data, size_t data_length)
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, 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