Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit cbfe725

Browse files
committed
[Linux] test FlViewAccessible
1 parent f3acc78 commit cbfe725

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
21022102
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
21032103
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible.cc
21042104
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible.h
2105+
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible_test.cc
21052106
FILE: ../../../flutter/shell/platform/linux/fl_view_private.h
21062107
FILE: ../../../flutter/shell/platform/linux/key_mapping.cc
21072108
FILE: ../../../flutter/shell/platform/linux/key_mapping.h

shell/platform/linux/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ executable("flutter_linux_unittests") {
203203
"fl_texture_gl_test.cc",
204204
"fl_texture_registrar_test.cc",
205205
"fl_value_test.cc",
206+
"fl_view_accessible_test.cc",
206207
"testing/fl_test.cc",
207208
"testing/mock_binary_messenger.cc",
208209
"testing/mock_binary_messenger_response_handle.cc",
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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/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+
const int32_t children[] = {111, 222};
19+
const FlutterSemanticsNode root_node = {
20+
.id = 0,
21+
.label = "root",
22+
.child_count = 2,
23+
.children_in_traversal_order = children,
24+
};
25+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
26+
27+
const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
28+
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);
29+
30+
const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
31+
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);
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(FlEngine) engine = make_mock_engine();
54+
g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
55+
g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));
56+
57+
FlutterSemanticsNode root_node = {
58+
.id = 0,
59+
.label = "root",
60+
.child_count = 0,
61+
};
62+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
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+
{
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+
const int32_t children[] = {111};
77+
root_node.child_count = 1;
78+
root_node.children_in_traversal_order = children;
79+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
80+
81+
const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
82+
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);
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+
{
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+
const int32_t children[] = {111, 222};
102+
root_node.child_count = 2;
103+
root_node.children_in_traversal_order = children;
104+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
105+
106+
const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
107+
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);
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+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
135+
}
136+
137+
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
138+
EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child2_object);
139+
140+
EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
141+
EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
142+
EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 0);
143+
EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
144+
145+
// remove child2
146+
{
147+
flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_removed(
148+
root_object, "children-changed::remove");
149+
EXPECT_SIGNAL2(child2_removed, ::testing::Eq(0),
150+
::testing::Eq(child2_object));
151+
152+
root_node.child_count = 0;
153+
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
154+
}
155+
156+
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
157+
}

0 commit comments

Comments
 (0)