Flutter Linux Embedder
fl_view_accessible_test.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Included first as it collides with the X11 headers.
6 #include "gtest/gtest.h"
7 
10 #include "flutter/shell/platform/linux/testing/fl_test.h"
11 #include "flutter/shell/platform/linux/testing/mock_signal_handler.h"
12 
13 TEST(FlViewAccessibleTest, BuildTree) {
14  g_autoptr(FlEngine) engine = make_mock_engine();
15  g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
16  g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));
17 
18  int32_t children[] = {111, 222};
19  FlutterSemanticsNode2 root_node = {
20  .id = 0,
21  .label = "root",
22  .child_count = 2,
23  .children_in_traversal_order = children,
24  };
25  FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
26  FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
27  FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
28  FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
30 
31  AtkObject* root_object =
32  atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
33  EXPECT_STREQ(atk_object_get_name(root_object), "root");
34  EXPECT_EQ(atk_object_get_index_in_parent(root_object), 0);
35  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
36 
37  AtkObject* child1_object = atk_object_ref_accessible_child(root_object, 0);
38  EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
39  EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
40  EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
41  EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
42 
43  AtkObject* child2_object = atk_object_ref_accessible_child(root_object, 1);
44  EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
45  EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
46  EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
47  EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
48 }
49 
50 TEST(FlViewAccessibleTest, AddRemoveChildren) {
51  g_autoptr(FlEngine) engine = make_mock_engine();
52  g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
53  g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));
54 
55  FlutterSemanticsNode2 root_node = {
56  .id = 0,
57  .label = "root",
58  .child_count = 0,
59  };
60  FlutterSemanticsNode2* nodes[1] = {&root_node};
61  FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
63 
64  AtkObject* root_object =
65  atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
66  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
67 
68  // add child1
69  AtkObject* child1_object = nullptr;
70  FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
71  {
72  flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_added(
73  root_object, "children-changed::add");
74  EXPECT_SIGNAL2(child1_added, ::testing::Eq(0), ::testing::A<AtkObject*>())
75  .WillOnce(::testing::SaveArg<1>(&child1_object));
76 
77  int32_t children[] = {111};
78  root_node.child_count = 1;
79  root_node.children_in_traversal_order = children;
80  FlutterSemanticsNode2* nodes[2] = {&root_node, &child1_node};
81  FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
83  }
84 
85  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
86  EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);
87 
88  EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
89  EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
90  EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
91  EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
92 
93  // add child2
94  AtkObject* child2_object = nullptr;
95  FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
96  {
97  flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_added(
98  root_object, "children-changed::add");
99  EXPECT_SIGNAL2(child2_added, ::testing::Eq(1), ::testing::A<AtkObject*>())
100  .WillOnce(::testing::SaveArg<1>(&child2_object));
101 
102  int32_t children[] = {111, 222};
103  root_node.child_count = 2;
104  root_node.children_in_traversal_order = children;
105  FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
106  FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
108  }
109 
110  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
111  EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);
112  EXPECT_EQ(atk_object_ref_accessible_child(root_object, 1), child2_object);
113 
114  EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
115  EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
116  EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
117  EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
118 
119  EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
120  EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
121  EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
122  EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
123 
124  // remove child1
125  {
126  flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_removed(
127  root_object, "children-changed::remove");
128  EXPECT_SIGNAL2(child1_removed, ::testing::Eq(0),
129  ::testing::Eq(child1_object));
130 
131  const int32_t children[] = {222};
132  root_node.child_count = 1;
133  root_node.children_in_traversal_order = children;
134  FlutterSemanticsNode2* nodes[3] = {&root_node, &child2_node};
135  FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
137  }
138 
139  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
140  EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child2_object);
141 
142  EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
143  EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
144  EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 0);
145  EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
146 
147  // remove child2
148  {
149  flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_removed(
150  root_object, "children-changed::remove");
151  EXPECT_SIGNAL2(child2_removed, ::testing::Eq(0),
152  ::testing::Eq(child2_object));
153 
154  root_node.child_count = 0;
155  FlutterSemanticsNode2* nodes[1] = {&root_node};
156  FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
158  }
159 
160  EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
161 }
fl_view_accessible.h
fl_view_accessible_handle_update_semantics
void fl_view_accessible_handle_update_semantics(FlViewAccessible *self, const FlutterSemanticsUpdate2 *update)
Definition: fl_view_accessible.cc:158
update
G_BEGIN_DECLS const FlutterSemanticsUpdate2 * update
Definition: fl_view_accessible.h:40
make_mock_engine
static FlEngine * make_mock_engine()
Definition: fl_event_channel_test.cc:24
TEST
TEST(FlViewAccessibleTest, BuildTree)
Definition: fl_view_accessible_test.cc:13
fl_engine.h
engine
FlEngine * engine
Definition: fl_view_accessible.cc:26