| 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
8 #include "flutter/shell/platform/linux/fl_view_accessible.h"
9 #include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
10 #include "flutter/shell/platform/linux/testing/mock_signal_handler.h"
11
12 TEST(FlViewAccessibleTest, BuildTree) {
13 g_autoptr(FlDartProject) project = fl_dart_project_new();
14 g_autoptr(FlEngine) engine = fl_engine_new(project);
15 g_autoptr(FlViewAccessible) accessible = fl_view_accessible_new(engine);
16
17 int32_t children[] = {111, 222};
18 FlutterSemanticsNode2 root_node = {
19 .id = 0,
20 .label = "root",
21 .child_count = 2,
22 .children_in_traversal_order = children,
23 };
24 FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
25 FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
26 FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
27 FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
28 fl_view_accessible_handle_update_semantics(accessible, &update);
29
30 AtkObject* root_object =
31 atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
32 EXPECT_STREQ(atk_object_get_name(root_object), "root");
33 EXPECT_EQ(atk_object_get_index_in_parent(root_object), 0);
34 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
35
36 AtkObject* child1_object = atk_object_ref_accessible_child(root_object, 0);
37 EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
38 EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
39 EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
40 EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
41
42 AtkObject* child2_object = atk_object_ref_accessible_child(root_object, 1);
43 EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
44 EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
45 EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
46 EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
47 }
48
49 TEST(FlViewAccessibleTest, AddRemoveChildren) {
50 g_autoptr(FlDartProject) project = fl_dart_project_new();
51 g_autoptr(FlEngine) engine = fl_engine_new(project);
52 g_autoptr(FlViewAccessible) accessible = fl_view_accessible_new(engine);
53
54 FlutterSemanticsNode2 root_node = {
55 .id = 0,
56 .label = "root",
57 .child_count = 0,
58 };
59 FlutterSemanticsNode2* nodes[1] = {&root_node};
60 FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
61 fl_view_accessible_handle_update_semantics(accessible, &update);
62
63 AtkObject* root_object =
64 atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
65 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
66
67 // add child1
68 AtkObject* child1_object = nullptr;
69 FlutterSemanticsNode2 child1_node = {.id = 111, .label = "child 1"};
70 {
71 flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_added(
72 root_object, "children-changed::add");
73 EXPECT_SIGNAL2(child1_added, ::testing::Eq(0), ::testing::A<AtkObject*>())
74 .WillOnce(::testing::SaveArg<1>(&child1_object));
75
76 int32_t children[] = {111};
77 root_node.child_count = 1;
78 root_node.children_in_traversal_order = children;
79 FlutterSemanticsNode2* nodes[2] = {&root_node, &child1_node};
80 FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
81 fl_view_accessible_handle_update_semantics(accessible, &update);
82 }
83
84 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
85 EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);
86
87 EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
88 EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
89 EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
90 EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
91
92 // add child2
93 AtkObject* child2_object = nullptr;
94 FlutterSemanticsNode2 child2_node = {.id = 222, .label = "child 2"};
95 {
96 flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_added(
97 root_object, "children-changed::add");
98 EXPECT_SIGNAL2(child2_added, ::testing::Eq(1), ::testing::A<AtkObject*>())
99 .WillOnce(::testing::SaveArg<1>(&child2_object));
100
101 int32_t children[] = {111, 222};
102 root_node.child_count = 2;
103 root_node.children_in_traversal_order = children;
104 FlutterSemanticsNode2* nodes[3] = {&root_node, &child1_node, &child2_node};
105 FlutterSemanticsUpdate2 update = {.node_count = 3, .nodes = nodes};
106 fl_view_accessible_handle_update_semantics(accessible, &update);
107 }
108
109 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
110 EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);
111 EXPECT_EQ(atk_object_ref_accessible_child(root_object, 1), child2_object);
112
113 EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
114 EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
115 EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
116 EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);
117
118 EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
119 EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
120 EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
121 EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
122
123 // remove child1
124 {
125 flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_removed(
126 root_object, "children-changed::remove");
127 EXPECT_SIGNAL2(child1_removed, ::testing::Eq(0),
128 ::testing::Eq(child1_object));
129
130 const int32_t children[] = {222};
131 root_node.child_count = 1;
132 root_node.children_in_traversal_order = children;
133 FlutterSemanticsNode2* nodes[3] = {&root_node, &child2_node};
134 FlutterSemanticsUpdate2 update = {.node_count = 2, .nodes = nodes};
135 fl_view_accessible_handle_update_semantics(accessible, &update);
136 }
137
138 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
139 EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child2_object);
140
141 EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
142 EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
143 EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 0);
144 EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
145
146 // remove child2
147 {
148 flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_removed(
149 root_object, "children-changed::remove");
150 EXPECT_SIGNAL2(child2_removed, ::testing::Eq(0),
151 ::testing::Eq(child2_object));
152
153 root_node.child_count = 0;
154 FlutterSemanticsNode2* nodes[1] = {&root_node};
155 FlutterSemanticsUpdate2 update = {.node_count = 1, .nodes = nodes};
156 fl_view_accessible_handle_update_semantics(accessible, &update);
157 }
158
159 EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
160 }
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:139
fl_dart_project_new
G_MODULE_EXPORT FlDartProject * fl_dart_project_new()
Definition: fl_dart_project.cc:50
TEST
TEST(FlViewAccessibleTest, BuildTree)
Definition: fl_view_accessible_test.cc:12
fl_engine_new
G_MODULE_EXPORT FlEngine * fl_engine_new(FlDartProject *project)
Definition: fl_engine.cc:524
fl_engine.h
fl_view_accessible_new
FlViewAccessible * fl_view_accessible_new(FlEngine *engine)
Definition: fl_view_accessible.cc:132