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