Flutter Linux Embedder
fl_accessible_text_field_test.cc File Reference
#include "gtest/gtest.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_accessible_text_field.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
#include "flutter/shell/platform/linux/testing/mock_signal_handler.h"

Go to the source code of this file.

Functions

static FlValuedecode_semantic_data (const uint8_t *data, size_t data_length)
 
 TEST (FlAccessibleTextFieldTest, SetValue)
 
 TEST (FlAccessibleTextFieldTest, SetTextSelection)
 
 TEST (FlAccessibleTextFieldTest, PerformAction)
 
 TEST (FlAccessibleTextFieldTest, GetCharacterCount)
 
 TEST (FlAccessibleTextFieldTest, GetText)
 
 TEST (FlAccessibleTextFieldTest, GetTextBoundsChecking)
 
 TEST (FlAccessibleTextFieldTest, GetCaretOffset)
 
 TEST (FlAccessibleTextFieldTest, SetCaretOffset)
 
 TEST (FlAccessibleTextFieldTest, GetNSelections)
 
 TEST (FlAccessibleTextFieldTest, GetSelection)
 
 TEST (FlAccessibleTextFieldTest, AddSelection)
 
 TEST (FlAccessibleTextFieldTest, RemoveSelection)
 
 TEST (FlAccessibleTextFieldTest, SetSelection)
 
 TEST (FlAccessibleTextFieldTest, SetTextContents)
 
 TEST (FlAccessibleTextFieldTest, InsertDeleteText)
 
 TEST (FlAccessibleTextFieldTest, CopyCutPasteText)
 
 TEST (FlAccessibleTextFieldTest, TextBoundary)
 
 TEST (FlAccessibleTextFieldTest, TextBoundaryOffsetBeyondEnd)
 
 TEST (FlAccessibleTextFieldTest, TextBoundaryOffsetAtStart)
 
 TEST (FlAccessibleTextFieldTest, TextBoundaryEmptyText)
 
 TEST (FlAccessibleTextFieldTest, TextBoundaryOffsetAtEnd)
 

Function Documentation

◆ decode_semantic_data()

static FlValue* decode_semantic_data ( const uint8_t *  data,
size_t  data_length 
)
static

Definition at line 17 of file fl_accessible_text_field_test.cc.

17  {
18  g_autoptr(GBytes) bytes = g_bytes_new(data, data_length);
19  g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
20  return fl_message_codec_decode_message(FL_MESSAGE_CODEC(codec), bytes,
21  nullptr);
22 }
g_autoptr(FlEngine) engine
G_MODULE_EXPORT FlValue * fl_message_codec_decode_message(FlMessageCodec *self, GBytes *message, GError **error)
G_MODULE_EXPORT FlStandardMessageCodec * fl_standard_message_codec_new()

References fl_message_codec_decode_message(), fl_standard_message_codec_new(), and g_autoptr().

Referenced by TEST().

◆ TEST() [1/21]

TEST ( FlAccessibleTextFieldTest  ,
AddSelection   
)

Definition at line 346 of file fl_accessible_text_field_test.cc.

346  {
347  int base = -1;
348  int extent = -1;
349 
350  g_autoptr(FlDartProject) project = fl_dart_project_new();
351  g_autoptr(FlEngine) engine = fl_engine_new(project);
352 
353  g_autoptr(GError) error = nullptr;
354  EXPECT_TRUE(fl_engine_start(engine, &error));
355  EXPECT_EQ(error, nullptr);
356 
357  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
358  SendSemanticsAction,
359  ([&base, &extent](auto engine,
360  const FlutterSendSemanticsActionInfo* info) {
361  EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
363  decode_semantic_data(info->data, info->data_length);
366  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
367  return kSuccess;
368  }));
369 
370  g_autoptr(FlAccessibleNode) node =
371  fl_accessible_text_field_new(engine, 123, 1);
372 
373  EXPECT_TRUE(atk_text_add_selection(ATK_TEXT(node), 2, 4));
374  EXPECT_EQ(base, 2);
375  EXPECT_EQ(extent, 4);
376 
378 
379  // already has selection
380  EXPECT_FALSE(atk_text_add_selection(ATK_TEXT(node), 6, 7));
381  EXPECT_EQ(base, 2);
382  EXPECT_EQ(extent, 4);
383 }
void fl_accessible_node_set_text_selection(FlAccessibleNode *self, gint base, gint extent)
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)
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
FlutterEngineProcTable * fl_engine_get_embedder_api(FlEngine *self)
Definition: fl_engine.cc:902
gboolean fl_engine_start(FlEngine *self, GError **error)
Definition: fl_engine.cc:760
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
Definition: fl_engine.cc:731
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition: fl_value.cc:668
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
@ FL_VALUE_TYPE_MAP
Definition: fl_value.h:74

References decode_semantic_data(), error, fl_accessible_node_set_text_selection(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, g_autoptr(), and value.

◆ TEST() [2/21]

TEST ( FlAccessibleTextFieldTest  ,
CopyCutPasteText   
)

Definition at line 556 of file fl_accessible_text_field_test.cc.

556  {
557  int base = -1;
558  int extent = -1;
559  FlutterSemanticsAction act = kFlutterSemanticsActionCustomAction;
560 
561  g_autoptr(FlDartProject) project = fl_dart_project_new();
562  g_autoptr(FlEngine) engine = fl_engine_new(project);
563 
564  g_autoptr(GError) error = nullptr;
565  EXPECT_TRUE(fl_engine_start(engine, &error));
566  EXPECT_EQ(error, nullptr);
567 
568  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
569  SendSemanticsAction,
570  ([&act, &base, &extent](auto engine,
571  const FlutterSendSemanticsActionInfo* info) {
572  EXPECT_THAT(info->action,
573  ::testing::AnyOf(kFlutterSemanticsActionCut,
574  kFlutterSemanticsActionCopy,
575  kFlutterSemanticsActionPaste,
576  kFlutterSemanticsActionSetSelection));
577  act = info->action;
578  if (info->action == kFlutterSemanticsActionSetSelection) {
580  decode_semantic_data(info->data, info->data_length);
583  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
584  }
585  return kSuccess;
586  }));
587 
588  g_autoptr(FlAccessibleNode) node =
589  fl_accessible_text_field_new(engine, 123, 1);
590 
591  atk_editable_text_copy_text(ATK_EDITABLE_TEXT(node), 2, 5);
592  EXPECT_EQ(base, 2);
593  EXPECT_EQ(extent, 5);
594  EXPECT_EQ(act, kFlutterSemanticsActionCopy);
595 
596  atk_editable_text_cut_text(ATK_EDITABLE_TEXT(node), 1, 4);
597  EXPECT_EQ(base, 1);
598  EXPECT_EQ(extent, 4);
599  EXPECT_EQ(act, kFlutterSemanticsActionCut);
600 
601  atk_editable_text_paste_text(ATK_EDITABLE_TEXT(node), 3);
602  EXPECT_EQ(base, 3);
603  EXPECT_EQ(extent, 3);
604  EXPECT_EQ(act, kFlutterSemanticsActionPaste);
605 }

References decode_semantic_data(), error, fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, g_autoptr(), and value.

◆ TEST() [3/21]

TEST ( FlAccessibleTextFieldTest  ,
GetCaretOffset   
)

Definition at line 249 of file fl_accessible_text_field_test.cc.

249  {
250  g_autoptr(FlDartProject) project = fl_dart_project_new();
251  g_autoptr(FlEngine) engine = fl_engine_new(project);
252  g_autoptr(FlAccessibleNode) node =
253  fl_accessible_text_field_new(engine, 123, 1);
254 
255  EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), -1);
256 
258 
259  EXPECT_EQ(atk_text_get_caret_offset(ATK_TEXT(node)), 2);
260 }

References fl_accessible_node_set_text_selection(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [4/21]

TEST ( FlAccessibleTextFieldTest  ,
GetCharacterCount   
)

Definition at line 186 of file fl_accessible_text_field_test.cc.

186  {
187  g_autoptr(FlDartProject) project = fl_dart_project_new();
188  g_autoptr(FlEngine) engine = fl_engine_new(project);
189  g_autoptr(FlAccessibleNode) node =
190  fl_accessible_text_field_new(engine, 123, 1);
191 
192  EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 0);
193 
194  fl_accessible_node_set_value(node, "Flutter!");
195 
196  EXPECT_EQ(atk_text_get_character_count(ATK_TEXT(node)), 8);
197 }
void fl_accessible_node_set_value(FlAccessibleNode *self, const gchar *value)

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [5/21]

TEST ( FlAccessibleTextFieldTest  ,
GetNSelections   
)

Definition at line 296 of file fl_accessible_text_field_test.cc.

296  {
297  g_autoptr(FlDartProject) project = fl_dart_project_new();
298  g_autoptr(FlEngine) engine = fl_engine_new(project);
299  g_autoptr(FlAccessibleNode) node =
300  fl_accessible_text_field_new(engine, 123, 1);
301 
302  EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 0);
303 
305 
306  EXPECT_EQ(atk_text_get_n_selections(ATK_TEXT(node)), 1);
307 }

References fl_accessible_node_set_text_selection(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [6/21]

TEST ( FlAccessibleTextFieldTest  ,
GetSelection   
)

Definition at line 310 of file fl_accessible_text_field_test.cc.

310  {
311  g_autoptr(FlDartProject) project = fl_dart_project_new();
312  g_autoptr(FlEngine) engine = fl_engine_new(project);
313  g_autoptr(FlAccessibleNode) node =
314  fl_accessible_text_field_new(engine, 123, 1);
315 
316  EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0, nullptr, nullptr),
317  nullptr);
318 
319  fl_accessible_node_set_value(node, "Flutter");
321 
322  gint start, end;
323  g_autofree gchar* selection =
324  atk_text_get_selection(ATK_TEXT(node), 0, &start, &end);
325  EXPECT_STREQ(selection, "utt");
326  EXPECT_EQ(start, 2);
327  EXPECT_EQ(end, 5);
328 
329  // reverse
331  g_autofree gchar* reverse =
332  atk_text_get_selection(ATK_TEXT(node), 0, &start, &end);
333  EXPECT_STREQ(reverse, "utt");
334  EXPECT_EQ(start, 2);
335  EXPECT_EQ(end, 5);
336 
337  // empty
339  EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 0, &start, &end), nullptr);
340 
341  // selection num != 0
342  EXPECT_EQ(atk_text_get_selection(ATK_TEXT(node), 1, &start, &end), nullptr);
343 }
glong glong end

References end, fl_accessible_node_set_text_selection(), fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), g_autoptr(), and start.

◆ TEST() [7/21]

TEST ( FlAccessibleTextFieldTest  ,
GetText   
)

Definition at line 200 of file fl_accessible_text_field_test.cc.

200  {
201  g_autoptr(FlDartProject) project = fl_dart_project_new();
202  g_autoptr(FlEngine) engine = fl_engine_new(project);
203  g_autoptr(FlAccessibleNode) node =
204  fl_accessible_text_field_new(engine, 123, 1);
205 
206  g_autofree gchar* empty = atk_text_get_text(ATK_TEXT(node), 0, -1);
207  EXPECT_STREQ(empty, "");
208 
209  flutter::testing::MockSignalHandler text_inserted(node, "text-insert");
210  EXPECT_SIGNAL(text_inserted).Times(1);
211 
212  fl_accessible_node_set_value(node, "Flutter!");
213 
214  g_autofree gchar* flutter = atk_text_get_text(ATK_TEXT(node), 0, -1);
215  EXPECT_STREQ(flutter, "Flutter!");
216 
217  g_autofree gchar* tt = atk_text_get_text(ATK_TEXT(node), 3, 5);
218  EXPECT_STREQ(tt, "tt");
219 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [8/21]

TEST ( FlAccessibleTextFieldTest  ,
GetTextBoundsChecking   
)

Definition at line 222 of file fl_accessible_text_field_test.cc.

222  {
223  g_autoptr(FlDartProject) project = fl_dart_project_new();
224  g_autoptr(FlEngine) engine = fl_engine_new(project);
225  g_autoptr(FlAccessibleNode) node =
226  fl_accessible_text_field_new(engine, 123, 1);
227 
228  fl_accessible_node_set_value(node, "Hello");
229 
230  // start beyond end of text
231  g_autofree gchar* beyond = atk_text_get_text(ATK_TEXT(node), 100, -1);
232  EXPECT_STREQ(beyond, "");
233 
234  // end beyond text length
235  g_autofree gchar* end_beyond = atk_text_get_text(ATK_TEXT(node), 2, 100);
236  EXPECT_STREQ(end_beyond, "llo");
237 
238  // both beyond text length
239  g_autofree gchar* both_beyond = atk_text_get_text(ATK_TEXT(node), 50, 100);
240  EXPECT_STREQ(both_beyond, "");
241 
242  // empty buffer
244  g_autofree gchar* empty_beyond = atk_text_get_text(ATK_TEXT(node), 5, 10);
245  EXPECT_STREQ(empty_beyond, "");
246 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [9/21]

TEST ( FlAccessibleTextFieldTest  ,
InsertDeleteText   
)

Definition at line 503 of file fl_accessible_text_field_test.cc.

503  {
504  g_autofree gchar* text = nullptr;
505  int base = -1;
506  int extent = -1;
507 
508  g_autoptr(FlDartProject) project = fl_dart_project_new();
509  g_autoptr(FlEngine) engine = fl_engine_new(project);
510 
511  g_autoptr(GError) error = nullptr;
512  EXPECT_TRUE(fl_engine_start(engine, &error));
513  EXPECT_EQ(error, nullptr);
514 
515  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
516  SendSemanticsAction,
517  ([&text, &base, &extent](auto engine,
518  const FlutterSendSemanticsActionInfo* info) {
519  EXPECT_THAT(info->action,
520  ::testing::AnyOf(kFlutterSemanticsActionSetText,
521  kFlutterSemanticsActionSetSelection));
522  if (info->action == kFlutterSemanticsActionSetText) {
524  decode_semantic_data(info->data, info->data_length);
526  g_free(text);
527  text = g_strdup(fl_value_get_string(value));
528  } else {
530  decode_semantic_data(info->data, info->data_length);
533  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
534  }
535  return kSuccess;
536  }));
537 
538  g_autoptr(FlAccessibleNode) node =
539  fl_accessible_text_field_new(engine, 123, 1);
540  fl_accessible_node_set_value(node, "Fler");
541 
542  gint pos = 2;
543  atk_editable_text_insert_text(ATK_EDITABLE_TEXT(node), "utt", 3, &pos);
544  EXPECT_EQ(pos, 5);
545  EXPECT_STREQ(text, "Flutter");
546  EXPECT_EQ(base, pos);
547  EXPECT_EQ(extent, pos);
548 
549  atk_editable_text_delete_text(ATK_EDITABLE_TEXT(node), 2, 5);
550  EXPECT_STREQ(text, "Fler");
551  EXPECT_EQ(base, 2);
552  EXPECT_EQ(extent, 2);
553 }
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:68

References decode_semantic_data(), error, fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_string(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, FL_VALUE_TYPE_STRING, g_autoptr(), and value.

◆ TEST() [10/21]

TEST ( FlAccessibleTextFieldTest  ,
PerformAction   
)

Definition at line 145 of file fl_accessible_text_field_test.cc.

145  {
146  g_autoptr(GPtrArray) action_datas = g_ptr_array_new_with_free_func(
147  reinterpret_cast<GDestroyNotify>(fl_value_unref));
148 
149  g_autoptr(FlDartProject) project = fl_dart_project_new();
150  g_autoptr(FlEngine) engine = fl_engine_new(project);
151 
152  g_autoptr(GError) error = nullptr;
153  EXPECT_TRUE(fl_engine_start(engine, &error));
154  EXPECT_EQ(error, nullptr);
155 
156  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
157  SendSemanticsAction,
158  ([&action_datas](auto engine,
159  const FlutterSendSemanticsActionInfo* info) {
160  g_ptr_array_add(action_datas,
161  decode_semantic_data(info->data, info->data_length));
162  return kSuccess;
163  }));
164 
165  g_autoptr(FlAccessibleNode) node =
166  fl_accessible_text_field_new(engine, 123, 1);
168  node, static_cast<FlutterSemanticsAction>(
169  kFlutterSemanticsActionMoveCursorForwardByCharacter |
170  kFlutterSemanticsActionMoveCursorBackwardByCharacter |
171  kFlutterSemanticsActionMoveCursorForwardByWord |
172  kFlutterSemanticsActionMoveCursorBackwardByWord));
173 
174  g_autoptr(FlValue) expand_selection = fl_value_new_bool(false);
175 
176  for (int i = 0; i < 4; ++i) {
177  atk_action_do_action(ATK_ACTION(node), i);
178 
179  FlValue* data = static_cast<FlValue*>(g_ptr_array_index(action_datas, i));
180  EXPECT_NE(data, nullptr);
181  EXPECT_TRUE(fl_value_equal(data, expand_selection));
182  }
183 }
void fl_accessible_node_set_actions(FlAccessibleNode *self, FlutterSemanticsAction actions)
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
Definition: fl_value.cc:400
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471

References decode_semantic_data(), error, fl_accessible_node_set_actions(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_equal(), fl_value_new_bool(), fl_value_unref(), g_autoptr(), and i.

◆ TEST() [11/21]

TEST ( FlAccessibleTextFieldTest  ,
RemoveSelection   
)

Definition at line 386 of file fl_accessible_text_field_test.cc.

386  {
387  int base = -1;
388  int extent = -1;
389 
390  g_autoptr(FlDartProject) project = fl_dart_project_new();
391  g_autoptr(FlEngine) engine = fl_engine_new(project);
392 
393  g_autoptr(GError) error = nullptr;
394  EXPECT_TRUE(fl_engine_start(engine, &error));
395  EXPECT_EQ(error, nullptr);
396 
397  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
398  SendSemanticsAction,
399  ([&base, &extent](auto engine,
400  const FlutterSendSemanticsActionInfo* info) {
401  EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
403  decode_semantic_data(info->data, info->data_length);
406  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
407  return kSuccess;
408  }));
409 
410  g_autoptr(FlAccessibleNode) node =
411  fl_accessible_text_field_new(engine, 123, 1);
412 
413  // no selection
414  EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 0));
415  EXPECT_EQ(base, -1);
416  EXPECT_EQ(extent, -1);
417 
419 
420  // selection num != 0
421  EXPECT_FALSE(atk_text_remove_selection(ATK_TEXT(node), 1));
422  EXPECT_EQ(base, -1);
423  EXPECT_EQ(extent, -1);
424 
425  // ok, collapses selection
426  EXPECT_TRUE(atk_text_remove_selection(ATK_TEXT(node), 0));
427  EXPECT_EQ(base, 4);
428  EXPECT_EQ(extent, 4);
429 }

References decode_semantic_data(), error, fl_accessible_node_set_text_selection(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, g_autoptr(), and value.

◆ TEST() [12/21]

TEST ( FlAccessibleTextFieldTest  ,
SetCaretOffset   
)

Definition at line 263 of file fl_accessible_text_field_test.cc.

263  {
264  int base = -1;
265  int extent = -1;
266 
267  g_autoptr(FlDartProject) project = fl_dart_project_new();
268  g_autoptr(FlEngine) engine = fl_engine_new(project);
269 
270  g_autoptr(GError) error = nullptr;
271  EXPECT_TRUE(fl_engine_start(engine, &error));
272  EXPECT_EQ(error, nullptr);
273 
274  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
275  SendSemanticsAction,
276  ([&base, &extent](auto engine,
277  const FlutterSendSemanticsActionInfo* info) {
278  EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
280  decode_semantic_data(info->data, info->data_length);
283  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
284  return kSuccess;
285  }));
286 
287  g_autoptr(FlAccessibleNode) node =
288  fl_accessible_text_field_new(engine, 123, 1);
289 
290  EXPECT_TRUE(atk_text_set_caret_offset(ATK_TEXT(node), 3));
291  EXPECT_EQ(base, 3);
292  EXPECT_EQ(extent, 3);
293 }

References decode_semantic_data(), error, fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, g_autoptr(), and value.

◆ TEST() [13/21]

TEST ( FlAccessibleTextFieldTest  ,
SetSelection   
)

Definition at line 432 of file fl_accessible_text_field_test.cc.

432  {
433  int base = -1;
434  int extent = -1;
435 
436  g_autoptr(FlDartProject) project = fl_dart_project_new();
437  g_autoptr(FlEngine) engine = fl_engine_new(project);
438 
439  g_autoptr(GError) error = nullptr;
440  EXPECT_TRUE(fl_engine_start(engine, &error));
441  EXPECT_EQ(error, nullptr);
442 
443  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
444  SendSemanticsAction,
445  ([&base, &extent](auto engine,
446  const FlutterSendSemanticsActionInfo* info) {
447  EXPECT_EQ(info->action, kFlutterSemanticsActionSetSelection);
449  decode_semantic_data(info->data, info->data_length);
452  extent = fl_value_get_int(fl_value_lookup_string(value, "extent"));
453  return kSuccess;
454  }));
455 
456  g_autoptr(FlAccessibleNode) node =
457  fl_accessible_text_field_new(engine, 123, 1);
458 
459  // selection num != 0
460  EXPECT_FALSE(atk_text_set_selection(ATK_TEXT(node), 1, 2, 4));
461  EXPECT_EQ(base, -1);
462  EXPECT_EQ(extent, -1);
463 
464  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 2, 4));
465  EXPECT_EQ(base, 2);
466  EXPECT_EQ(extent, 4);
467 
468  EXPECT_TRUE(atk_text_set_selection(ATK_TEXT(node), 0, 5, 1));
469  EXPECT_EQ(base, 5);
470  EXPECT_EQ(extent, 1);
471 }

References decode_semantic_data(), error, fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_int(), fl_value_get_type(), fl_value_lookup_string(), FL_VALUE_TYPE_MAP, g_autoptr(), and value.

◆ TEST() [14/21]

TEST ( FlAccessibleTextFieldTest  ,
SetTextContents   
)

Definition at line 474 of file fl_accessible_text_field_test.cc.

474  {
475  g_autofree gchar* text = nullptr;
476 
477  g_autoptr(FlDartProject) project = fl_dart_project_new();
478  g_autoptr(FlEngine) engine = fl_engine_new(project);
479 
480  g_autoptr(GError) error = nullptr;
481  EXPECT_TRUE(fl_engine_start(engine, &error));
482  EXPECT_EQ(error, nullptr);
483 
484  fl_engine_get_embedder_api(engine)->SendSemanticsAction = MOCK_ENGINE_PROC(
485  SendSemanticsAction,
486  ([&text](auto engine, const FlutterSendSemanticsActionInfo* info) {
487  EXPECT_EQ(info->action, kFlutterSemanticsActionSetText);
489  decode_semantic_data(info->data, info->data_length);
491  text = g_strdup(fl_value_get_string(value));
492  return kSuccess;
493  }));
494 
495  g_autoptr(FlAccessibleNode) node =
496  fl_accessible_text_field_new(engine, 123, 1);
497 
498  atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(node), "Flutter");
499  EXPECT_STREQ(text, "Flutter");
500 }

References decode_semantic_data(), error, fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_get_embedder_api(), fl_engine_new(), fl_engine_start(), fl_value_get_string(), fl_value_get_type(), FL_VALUE_TYPE_STRING, g_autoptr(), and value.

◆ TEST() [15/21]

TEST ( FlAccessibleTextFieldTest  ,
SetTextSelection   
)

Definition at line 84 of file fl_accessible_text_field_test.cc.

84  {
85  g_autoptr(FlDartProject) project = fl_dart_project_new();
86  g_autoptr(FlEngine) engine = fl_engine_new(project);
87  g_autoptr(FlAccessibleNode) node =
88  fl_accessible_text_field_new(engine, 123, 1);
89 
90  // [-1,-1] -> [2,3]
91  {
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");
96 
97  EXPECT_SIGNAL(text_selection_changed);
98  EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(3));
99 
101  }
102 
103  // [2,3] -> [3,3]
104  {
105  flutter::testing::MockSignalHandler text_selection_changed(
106  node, "text-selection-changed");
107  flutter::testing::MockSignalHandler text_caret_moved(node,
108  "text-caret-moved");
109 
110  EXPECT_SIGNAL(text_selection_changed);
111  EXPECT_SIGNAL(text_caret_moved).Times(0);
112 
114  }
115 
116  // [3,3] -> [3,3]
117  {
118  flutter::testing::MockSignalHandler text_selection_changed(
119  node, "text-selection-changed");
120  flutter::testing::MockSignalHandler text_caret_moved(node,
121  "text-caret-moved");
122 
123  EXPECT_SIGNAL(text_selection_changed).Times(0);
124  EXPECT_SIGNAL(text_caret_moved).Times(0);
125 
127  }
128 
129  // [3,3] -> [4,4]
130  {
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");
135 
136  EXPECT_SIGNAL(text_selection_changed).Times(0);
137  EXPECT_SIGNAL1(text_caret_moved, ::testing::Eq(4));
138 
140  }
141 }

References fl_accessible_node_set_text_selection(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [16/21]

TEST ( FlAccessibleTextFieldTest  ,
SetValue   
)

Definition at line 26 of file fl_accessible_text_field_test.cc.

26  {
27  g_autoptr(FlDartProject) project = fl_dart_project_new();
28  g_autoptr(FlEngine) engine = fl_engine_new(project);
29  g_autoptr(FlAccessibleNode) node =
30  fl_accessible_text_field_new(engine, 123, 1);
31 
32  // "" -> "Flutter"
33  {
34  flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
35  "text-insert");
36  flutter::testing::MockSignalHandler text_removed(node, "text-remove");
37 
38  EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(7));
39  EXPECT_SIGNAL(text_removed).Times(0);
40 
41  fl_accessible_node_set_value(node, "Flutter");
42  }
43 
44  // "Flutter" -> "Flutter"
45  {
46  flutter::testing::MockSignalHandler text_inserted(node, "text-insert");
47  flutter::testing::MockSignalHandler text_removed(node, "text-remove");
48 
49  EXPECT_SIGNAL(text_inserted).Times(0);
50  EXPECT_SIGNAL(text_removed).Times(0);
51 
52  fl_accessible_node_set_value(node, "Flutter");
53  }
54 
55  // "Flutter" -> "engine"
56  {
57  flutter::testing::MockSignalHandler2<int, int> text_inserted(node,
58  "text-insert");
59  flutter::testing::MockSignalHandler2<int, int> text_removed(node,
60  "text-remove");
61 
62  EXPECT_SIGNAL2(text_inserted, ::testing::Eq(0), ::testing::Eq(6));
63  EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(7));
64 
65  fl_accessible_node_set_value(node, "engine");
66  }
67 
68  // "engine" -> ""
69  {
70  flutter::testing::MockSignalHandler text_inserted(node, "text-insert");
71  flutter::testing::MockSignalHandler2<int, int> text_removed(node,
72  "text-remove");
73 
74  EXPECT_SIGNAL(text_inserted).Times(0);
75  EXPECT_SIGNAL2(text_removed, ::testing::Eq(0), ::testing::Eq(6));
76 
78  }
79 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [17/21]

TEST ( FlAccessibleTextFieldTest  ,
TextBoundary   
)

Definition at line 607 of file fl_accessible_text_field_test.cc.

607  {
608  g_autoptr(FlDartProject) project = fl_dart_project_new();
609  g_autoptr(FlEngine) engine = fl_engine_new(project);
610  g_autoptr(FlAccessibleNode) node =
611  fl_accessible_text_field_new(engine, 123, 1);
612 
614  "Lorem ipsum.\nDolor sit amet. Praesent commodo?"
615  "\n\nPraesent et felis dui.");
616 
617  // |Lorem
618  gint start_offset = -1, end_offset = -1;
619  g_autofree gchar* lorem_char = atk_text_get_string_at_offset(
620  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
621  EXPECT_STREQ(lorem_char, "L");
622  EXPECT_EQ(start_offset, 0);
623  EXPECT_EQ(end_offset, 1);
624 
625  g_autofree gchar* lorem_word = atk_text_get_string_at_offset(
626  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
627  EXPECT_STREQ(lorem_word, "Lorem");
628  EXPECT_EQ(start_offset, 0);
629  EXPECT_EQ(end_offset, 5);
630 
631  g_autofree gchar* lorem_sentence = atk_text_get_string_at_offset(
632  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
633  &end_offset);
634  EXPECT_STREQ(lorem_sentence, "Lorem ipsum.");
635  EXPECT_EQ(start_offset, 0);
636  EXPECT_EQ(end_offset, 12);
637 
638  g_autofree gchar* lorem_line = atk_text_get_string_at_offset(
639  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_LINE, &start_offset, &end_offset);
640  EXPECT_STREQ(lorem_line, "Lorem ipsum.");
641  EXPECT_EQ(start_offset, 0);
642  EXPECT_EQ(end_offset, 12);
643 
644  g_autofree gchar* lorem_paragraph = atk_text_get_string_at_offset(
645  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
646  &end_offset);
647  EXPECT_STREQ(lorem_paragraph,
648  "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
649  EXPECT_EQ(start_offset, 0);
650  EXPECT_EQ(end_offset, 46);
651 
652  // Pra|esent
653  g_autofree gchar* praesent_char = atk_text_get_string_at_offset(
654  ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
655  &end_offset);
656  EXPECT_STREQ(praesent_char, "e");
657  EXPECT_EQ(start_offset, 32);
658  EXPECT_EQ(end_offset, 33);
659 
660  g_autofree gchar* praesent_word = atk_text_get_string_at_offset(
661  ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_WORD, &start_offset,
662  &end_offset);
663  EXPECT_STREQ(praesent_word, "Praesent");
664  EXPECT_EQ(start_offset, 29);
665  EXPECT_EQ(end_offset, 37);
666 
667  g_autofree gchar* praesent_sentence = atk_text_get_string_at_offset(
668  ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
669  &end_offset);
670  EXPECT_STREQ(praesent_sentence, "Praesent commodo?");
671  EXPECT_EQ(start_offset, 29);
672  EXPECT_EQ(end_offset, 46);
673 
674  g_autofree gchar* praesent_line = atk_text_get_string_at_offset(
675  ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_LINE, &start_offset,
676  &end_offset);
677  EXPECT_STREQ(praesent_line, "Dolor sit amet. Praesent commodo?");
678  EXPECT_EQ(start_offset, 13);
679  EXPECT_EQ(end_offset, 46);
680 
681  g_autofree gchar* praesent_paragraph = atk_text_get_string_at_offset(
682  ATK_TEXT(node), 32, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
683  &end_offset);
684  EXPECT_STREQ(praesent_paragraph,
685  "Lorem ipsum.\nDolor sit amet. Praesent commodo?");
686  EXPECT_EQ(start_offset, 0);
687  EXPECT_EQ(end_offset, 46);
688 
689  // feli|s
690  g_autofree gchar* felis_char = atk_text_get_string_at_offset(
691  ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
692  &end_offset);
693  EXPECT_STREQ(felis_char, "s");
694  EXPECT_EQ(start_offset, 64);
695  EXPECT_EQ(end_offset, 65);
696 
697  g_autofree gchar* felis_word = atk_text_get_string_at_offset(
698  ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_WORD, &start_offset,
699  &end_offset);
700  EXPECT_STREQ(felis_word, "felis");
701  EXPECT_EQ(start_offset, 60);
702  EXPECT_EQ(end_offset, 65);
703 
704  g_autofree gchar* felis_sentence = atk_text_get_string_at_offset(
705  ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
706  &end_offset);
707  EXPECT_STREQ(felis_sentence, "Praesent et felis dui.");
708  EXPECT_EQ(start_offset, 48);
709  EXPECT_EQ(end_offset, 70);
710 
711  g_autofree gchar* felis_line = atk_text_get_string_at_offset(
712  ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_LINE, &start_offset,
713  &end_offset);
714  EXPECT_STREQ(felis_line, "Praesent et felis dui.");
715  EXPECT_EQ(start_offset, 48);
716  EXPECT_EQ(end_offset, 70);
717 
718  g_autofree gchar* felis_paragraph = atk_text_get_string_at_offset(
719  ATK_TEXT(node), 64, ATK_TEXT_GRANULARITY_PARAGRAPH, &start_offset,
720  &end_offset);
721  EXPECT_STREQ(felis_paragraph, "\nPraesent et felis dui.");
722  EXPECT_EQ(start_offset, 47);
723  EXPECT_EQ(end_offset, 70);
724 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [18/21]

TEST ( FlAccessibleTextFieldTest  ,
TextBoundaryEmptyText   
)

Definition at line 787 of file fl_accessible_text_field_test.cc.

787  {
788  g_autoptr(FlDartProject) project = fl_dart_project_new();
789  g_autoptr(FlEngine) engine = fl_engine_new(project);
790  g_autoptr(FlAccessibleNode) node =
791  fl_accessible_text_field_new(engine, 123, 1);
792 
793  // Empty text - should not crash.
794  gint start_offset = -1, end_offset = -1;
795  g_autofree gchar* char_result = atk_text_get_string_at_offset(
796  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
797  EXPECT_NE(char_result, nullptr);
798  EXPECT_EQ(start_offset, 0);
799  EXPECT_STREQ(char_result, "");
800 
801  g_autofree gchar* word_result = atk_text_get_string_at_offset(
802  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
803  EXPECT_NE(word_result, nullptr);
804  EXPECT_EQ(start_offset, 0);
805  EXPECT_STREQ(word_result, "");
806 }

References fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [19/21]

TEST ( FlAccessibleTextFieldTest  ,
TextBoundaryOffsetAtEnd   
)

Definition at line 809 of file fl_accessible_text_field_test.cc.

809  {
810  g_autoptr(FlDartProject) project = fl_dart_project_new();
811  g_autoptr(FlEngine) engine = fl_engine_new(project);
812  g_autoptr(FlAccessibleNode) node =
813  fl_accessible_text_field_new(engine, 123, 1);
814 
815  fl_accessible_node_set_value(node, "Hello world");
816 
817  // Offset at exactly the character count (one past last char).
818  gint char_count = atk_text_get_character_count(ATK_TEXT(node));
819  EXPECT_EQ(char_count, 11);
820 
821  gint start_offset = -1, end_offset = -1;
822  g_autofree gchar* char_result = atk_text_get_string_at_offset(
823  ATK_TEXT(node), char_count, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
824  &end_offset);
825  EXPECT_NE(char_result, nullptr);
826  EXPECT_GE(start_offset, 0);
827  EXPECT_LE(end_offset, char_count);
828 
829  g_autofree gchar* word_result = atk_text_get_string_at_offset(
830  ATK_TEXT(node), char_count, ATK_TEXT_GRANULARITY_WORD, &start_offset,
831  &end_offset);
832  EXPECT_NE(word_result, nullptr);
833  EXPECT_GE(start_offset, 0);
834  EXPECT_LE(end_offset, char_count);
835 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [20/21]

TEST ( FlAccessibleTextFieldTest  ,
TextBoundaryOffsetAtStart   
)

Definition at line 761 of file fl_accessible_text_field_test.cc.

761  {
762  g_autoptr(FlDartProject) project = fl_dart_project_new();
763  g_autoptr(FlEngine) engine = fl_engine_new(project);
764  g_autoptr(FlAccessibleNode) node =
765  fl_accessible_text_field_new(engine, 123, 1);
766 
767  fl_accessible_node_set_value(node, "Hello");
768 
769  // Offset at zero should return the first character/word.
770  gint start_offset = -1, end_offset = -1;
771  g_autofree gchar* char_result = atk_text_get_string_at_offset(
772  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_CHAR, &start_offset, &end_offset);
773  EXPECT_NE(char_result, nullptr);
774  EXPECT_EQ(start_offset, 0);
775  EXPECT_EQ(end_offset, 1);
776  EXPECT_STREQ(char_result, "H");
777 
778  g_autofree gchar* word_result = atk_text_get_string_at_offset(
779  ATK_TEXT(node), 0, ATK_TEXT_GRANULARITY_WORD, &start_offset, &end_offset);
780  EXPECT_NE(word_result, nullptr);
781  EXPECT_EQ(start_offset, 0);
782  EXPECT_EQ(end_offset, 5);
783  EXPECT_STREQ(word_result, "Hello");
784 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().

◆ TEST() [21/21]

TEST ( FlAccessibleTextFieldTest  ,
TextBoundaryOffsetBeyondEnd   
)

Definition at line 727 of file fl_accessible_text_field_test.cc.

727  {
728  g_autoptr(FlDartProject) project = fl_dart_project_new();
729  g_autoptr(FlEngine) engine = fl_engine_new(project);
730  g_autoptr(FlAccessibleNode) node =
731  fl_accessible_text_field_new(engine, 123, 1);
732 
733  fl_accessible_node_set_value(node, "Hello");
734 
735  // Offset well beyond the text length should not crash and should return
736  // a valid result clamped to the text boundaries.
737  gint start_offset = -1, end_offset = -1;
738  g_autofree gchar* char_result = atk_text_get_string_at_offset(
739  ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_CHAR, &start_offset,
740  &end_offset);
741  EXPECT_NE(char_result, nullptr);
742  EXPECT_GE(start_offset, 0);
743  EXPECT_LE(end_offset, 5);
744 
745  g_autofree gchar* word_result = atk_text_get_string_at_offset(
746  ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_WORD, &start_offset,
747  &end_offset);
748  EXPECT_NE(word_result, nullptr);
749  EXPECT_GE(start_offset, 0);
750  EXPECT_LE(end_offset, 5);
751 
752  g_autofree gchar* sentence_result = atk_text_get_string_at_offset(
753  ATK_TEXT(node), 100, ATK_TEXT_GRANULARITY_SENTENCE, &start_offset,
754  &end_offset);
755  EXPECT_NE(sentence_result, nullptr);
756  EXPECT_GE(start_offset, 0);
757  EXPECT_LE(end_offset, 5);
758 }

References fl_accessible_node_set_value(), fl_accessible_text_field_new(), fl_dart_project_new(), fl_engine_new(), and g_autoptr().