Skip to content

Commit

Permalink
[Linux] test FlViewAccessible
Browse files Browse the repository at this point in the history
  • Loading branch information
jpnurmi committed Apr 19, 2022
1 parent f3acc78 commit cbfe725
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2102,6 +2102,7 @@ FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible.cc
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible.h
FILE: ../../../flutter/shell/platform/linux/fl_view_accessible_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_view_private.h
FILE: ../../../flutter/shell/platform/linux/key_mapping.cc
FILE: ../../../flutter/shell/platform/linux/key_mapping.h
Expand Down
1 change: 1 addition & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ executable("flutter_linux_unittests") {
"fl_texture_gl_test.cc",
"fl_texture_registrar_test.cc",
"fl_value_test.cc",
"fl_view_accessible_test.cc",
"testing/fl_test.cc",
"testing/mock_binary_messenger.cc",
"testing/mock_binary_messenger_response_handle.cc",
Expand Down
157 changes: 157 additions & 0 deletions shell/platform/linux/fl_view_accessible_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Included first as it collides with the X11 headers.
#include "gtest/gtest.h"

#include "flutter/shell/platform/linux/fl_view_accessible.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/testing/fl_test.h"
#include "flutter/shell/platform/linux/testing/mock_signal_handler.h"

TEST(FlViewAccessibleTest, BuildTree) {
g_autoptr(FlEngine) engine = make_mock_engine();
g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));

const int32_t children[] = {111, 222};
const FlutterSemanticsNode root_node = {
.id = 0,
.label = "root",
.child_count = 2,
.children_in_traversal_order = children,
};
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);

const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);

const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);

AtkObject* root_object =
atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
EXPECT_STREQ(atk_object_get_name(root_object), "root");
EXPECT_EQ(atk_object_get_index_in_parent(root_object), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);

AtkObject* child1_object = atk_object_ref_accessible_child(root_object, 0);
EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);

AtkObject* child2_object = atk_object_ref_accessible_child(root_object, 1);
EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);
}

TEST(FlViewAccessibleTest, AddRemoveChildren) {
g_autoptr(FlEngine) engine = make_mock_engine();
g_autoptr(FlViewAccessible) accessible = FL_VIEW_ACCESSIBLE(
g_object_new(fl_view_accessible_get_type(), "engine", engine, nullptr));

FlutterSemanticsNode root_node = {
.id = 0,
.label = "root",
.child_count = 0,
};
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);

AtkObject* root_object =
atk_object_ref_accessible_child(ATK_OBJECT(accessible), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);

// add child1
AtkObject* child1_object = nullptr;
{
flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_added(
root_object, "children-changed::add");
EXPECT_SIGNAL2(child1_added, ::testing::Eq(0), ::testing::A<AtkObject*>())
.WillOnce(::testing::SaveArg<1>(&child1_object));

const int32_t children[] = {111};
root_node.child_count = 1;
root_node.children_in_traversal_order = children;
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);

const FlutterSemanticsNode child1_node = {.id = 111, .label = "child 1"};
fl_view_accessible_handle_update_semantics_node(accessible, &child1_node);
}

EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);

EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);

// add child2
AtkObject* child2_object = nullptr;
{
flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_added(
root_object, "children-changed::add");
EXPECT_SIGNAL2(child2_added, ::testing::Eq(1), ::testing::A<AtkObject*>())
.WillOnce(::testing::SaveArg<1>(&child2_object));

const int32_t children[] = {111, 222};
root_node.child_count = 2;
root_node.children_in_traversal_order = children;
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);

const FlutterSemanticsNode child2_node = {.id = 222, .label = "child 2"};
fl_view_accessible_handle_update_semantics_node(accessible, &child2_node);
}

EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 2);
EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child1_object);
EXPECT_EQ(atk_object_ref_accessible_child(root_object, 1), child2_object);

EXPECT_STREQ(atk_object_get_name(child1_object), "child 1");
EXPECT_EQ(atk_object_get_parent(child1_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child1_object), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(child1_object), 0);

EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 1);
EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);

// remove child1
{
flutter::testing::MockSignalHandler2<gint, AtkObject*> child1_removed(
root_object, "children-changed::remove");
EXPECT_SIGNAL2(child1_removed, ::testing::Eq(0),
::testing::Eq(child1_object));

const int32_t children[] = {222};
root_node.child_count = 1;
root_node.children_in_traversal_order = children;
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
}

EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 1);
EXPECT_EQ(atk_object_ref_accessible_child(root_object, 0), child2_object);

EXPECT_STREQ(atk_object_get_name(child2_object), "child 2");
EXPECT_EQ(atk_object_get_parent(child2_object), root_object);
EXPECT_EQ(atk_object_get_index_in_parent(child2_object), 0);
EXPECT_EQ(atk_object_get_n_accessible_children(child2_object), 0);

// remove child2
{
flutter::testing::MockSignalHandler2<gint, AtkObject*> child2_removed(
root_object, "children-changed::remove");
EXPECT_SIGNAL2(child2_removed, ::testing::Eq(0),
::testing::Eq(child2_object));

root_node.child_count = 0;
fl_view_accessible_handle_update_semantics_node(accessible, &root_node);
}

EXPECT_EQ(atk_object_get_n_accessible_children(root_object), 0);
}

0 comments on commit cbfe725

Please sign in to comment.