Index: ui/accessibility/ax_node_position_unittest.cc |
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..02e1703c2118a42dc3ca12cff52ff36c02cd83e1 |
--- /dev/null |
+++ b/ui/accessibility/ax_node_position_unittest.cc |
@@ -0,0 +1,423 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stdint.h> |
+ |
+#include <memory> |
+#include <vector> |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/accessibility/ax_enums.h" |
+#include "ui/accessibility/ax_node.h" |
+#include "ui/accessibility/ax_node_data.h" |
+#include "ui/accessibility/ax_node_position.h" |
+#include "ui/accessibility/ax_serializable_tree.h" |
+#include "ui/accessibility/ax_tree_serializer.h" |
+#include "ui/accessibility/ax_tree_update.h" |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+class AXTreeTest : public testing::Test { |
+ public: |
+ const char* TEXT_VALUE = "Line 1\nLine 2"; |
+ |
+ AXTreeTest(); |
+ ~AXTreeTest() override; |
+ |
+ protected: |
+ void SetUp() override; |
+ void TearDown() override; |
+ |
+ AXNodeData root_; |
+ AXNodeData button_; |
+ AXNodeData check_box_; |
+ AXNodeData text_field_; |
+ AXNodeData static_text1_; |
+ AXNodeData line_break_; |
+ AXNodeData static_text2_; |
+ AXNodeData inline_box1_; |
+ AXNodeData inline_box2_; |
+ |
+ AXTree tree_; |
+ DISALLOW_COPY_AND_ASSIGN(AXTreeTest); |
+}; |
+ |
+AXTreeTest::AXTreeTest() {} |
+ |
+AXTreeTest::~AXTreeTest() {} |
+ |
+void AXTreeTest::SetUp() { |
+ std::vector<int32_t> line_start_offsets{0, 6}; |
+ std::vector<int32_t> word_starts{0, 5}; |
+ std::vector<int32_t> word_ends{3, 6}; |
+ |
+ root_.id = 1; |
+ root_.role = AX_ROLE_DIALOG; |
+ root_.state = 1 << AX_STATE_FOCUSABLE; |
+ root_.location = gfx::RectF(0, 0, 800, 600); |
+ |
+ button_.id = 2; |
+ button_.role = AX_ROLE_BUTTON; |
+ button_.state = 1 << AX_STATE_HASPOPUP; |
+ button_.SetName("Sample button_"); |
+ button_.location = gfx::RectF(20, 20, 200, 30); |
+ root_.child_ids.push_back(button_.id); |
+ |
+ check_box_.id = 3; |
+ check_box_.role = AX_ROLE_CHECK_BOX; |
+ check_box_.state = 1 << AX_STATE_CHECKED; |
+ check_box_.SetName("Sample check box"); |
+ check_box_.location = gfx::RectF(20, 50, 200, 30); |
+ root_.child_ids.push_back(check_box_.id); |
+ |
+ text_field_.id = 4; |
+ text_field_.role = AX_ROLE_TEXT_FIELD; |
+ text_field_.state = 1 << AX_STATE_EDITABLE; |
+ text_field_.SetValue(TEXT_VALUE); |
+ text_field_.AddIntListAttribute(AX_ATTR_CACHED_LINE_STARTS, |
+ line_start_offsets); |
+ text_field_.child_ids.push_back(static_text1_.id); |
+ text_field_.child_ids.push_back(line_break_.id); |
+ text_field_.child_ids.push_back(static_text2_.id); |
+ root_.child_ids.push_back(text_field_.id); |
+ |
+ static_text1_.id = 5; |
+ static_text1_.role = AX_ROLE_STATIC_TEXT; |
+ static_text1_.state = 1 << AX_STATE_EDITABLE; |
+ static_text1_.SetName("Line 1"); |
+ static_text1_.child_ids.push_back(inline_box1_.id); |
+ |
+ inline_box1_.id = 6; |
+ inline_box1_.role = AX_ROLE_INLINE_TEXT_BOX; |
+ inline_box1_.state = 1 << AX_STATE_EDITABLE; |
+ inline_box1_.SetName("Line 1"); |
+ inline_box1_.AddIntListAttribute(AX_ATTR_WORD_STARTS, word_starts); |
+ inline_box1_.AddIntListAttribute(AX_ATTR_WORD_ENDS, word_ends); |
+ |
+ line_break_.id = 7; |
+ line_break_.role = AX_ROLE_LINE_BREAK; |
+ line_break_.state = 1 << AX_STATE_EDITABLE; |
+ line_break_.SetName("\n"); |
+ |
+ static_text2_.id = 8; |
+ static_text2_.role = AX_ROLE_STATIC_TEXT; |
+ static_text2_.state = 1 << AX_STATE_EDITABLE; |
+ static_text2_.SetName("Line 2"); |
+ static_text2_.child_ids.push_back(inline_box2_.id); |
+ |
+ inline_box2_.id = 9; |
+ inline_box2_.role = AX_ROLE_INLINE_TEXT_BOX; |
+ inline_box2_.state = 1 << AX_STATE_EDITABLE; |
+ inline_box2_.SetName("Line 2"); |
+ inline_box2_.AddIntListAttribute(AX_ATTR_WORD_STARTS, word_starts); |
+ inline_box2_.AddIntListAttribute(AX_ATTR_WORD_ENDS, word_ends); |
+ |
+ AXTreeUpdate initial_state; |
+ initial_state.root_id = 1; |
+ initial_state.nodes.push_back(root_); |
+ initial_state.nodes.push_back(button_); |
+ initial_state.nodes.push_back(check_box_); |
+ initial_state.nodes.push_back(text_field_); |
+ initial_state.nodes.push_back(static_text1_); |
+ initial_state.nodes.push_back(inline_box1_); |
+ initial_state.nodes.push_back(line_break_); |
+ initial_state.nodes.push_back(static_text2_); |
+ initial_state.nodes.push_back(inline_box2_); |
+ initial_state.has_tree_data = true; |
+ initial_state.tree_data.tree_id = 0; |
+ initial_state.tree_data.title = "Dialog title"; |
+ AXSerializableTree src_tree(initial_state); |
+ |
+ std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>> |
+ tree_source(src_tree.CreateTreeSource()); |
+ AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData> serializer( |
+ tree_source.get()); |
+ AXTreeUpdate update; |
+ serializer.SerializeChanges(src_tree.root(), &update); |
+ ASSERT_TRUE(tree_.Unserialize(update)); |
+ AXNodePosition::SetTreeForTesting(&tree_); |
+} |
+ |
+void AXTreeTest::TearDown() { |
+ AXNodePosition::SetTreeForTesting(nullptr); |
+} |
+ |
+} // namespace |
+ |
+TEST_F(AXTreeTest, AtStartOfAnchorWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
dmazzoni
2016/10/12 20:45:41
How about a typedef for AXPosition<AXNodePosition,
|
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ EXPECT_FALSE(null_position->AtStartOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, AtStartOfAnchorWithTreePosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> tree_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 0 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ EXPECT_TRUE(tree_position->AtStartOfAnchor()); |
+ |
+ tree_position.reset(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, root_.id, 1 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ EXPECT_FALSE(tree_position->AtStartOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, AtStartOfAnchorWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, |
+ 0 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ EXPECT_TRUE(text_position->AtStartOfAnchor()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ EXPECT_FALSE(text_position->AtStartOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, AtEndOfAnchorWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ EXPECT_FALSE(null_position->AtEndOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, AtEndOfAnchorWithTreePosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> tree_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 2 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ EXPECT_TRUE(tree_position->AtEndOfAnchor()); |
+ |
+ tree_position.reset(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, root_.id, 1 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ EXPECT_FALSE(tree_position->AtEndOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, AtEndOfAnchorWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, |
+ 6 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ EXPECT_TRUE(text_position->AtEndOfAnchor()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ EXPECT_FALSE(text_position->AtEndOfAnchor()); |
+} |
+ |
+TEST_F(AXTreeTest, CommonAncestor) { |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> button_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 0 /* child_index */)); |
+ ASSERT_NE(nullptr, button_position); |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> text_field_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 2 /* child_index */)); |
+ ASSERT_NE(nullptr, text_field_position); |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> |
+ static_text1_position(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, text_field_.id, 0 /* child_index */)); |
+ ASSERT_NE(nullptr, static_text1_position); |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> |
+ static_text2_position(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, text_field_.id, 2 /* child_index */)); |
+ ASSERT_NE(nullptr, static_text2_position); |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> |
+ inline_box1_position(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */)); |
+ ASSERT_NE(nullptr, inline_box1_position); |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> |
+ inline_box2_position(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */)); |
+ ASSERT_NE(nullptr, inline_box2_position); |
+ |
+ std::unique_ptr<const AXPosition<AXNodePosition, AXNode>> test_position( |
+ button_position->CommonAncestor(*text_field_position)); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(root_.id, test_position->get_anchor_id()); |
+ |
+ test_position.reset( |
+ static_text2_position->CommonAncestor(*static_text1_position)); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(text_field_.id, test_position->get_anchor_id()); |
+ |
+ test_position.reset( |
+ static_text1_position->CommonAncestor(*text_field_position)); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(text_field_.id, test_position->get_anchor_id()); |
+ |
+ test_position.reset( |
+ inline_box1_position->CommonAncestor(*inline_box2_position)); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(text_field_.id, test_position->get_anchor_id()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtStartOfAnchorWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ null_position->GetPositionAtStartOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_TRUE(test_position->IsNullPosition()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtStartOfAnchorWithTreePosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> tree_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 0 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ tree_position->GetPositionAtStartOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(root_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_child_index()); |
+ |
+ tree_position.reset(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, root_.id, 1 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ test_position.reset(tree_position->GetPositionAtStartOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(root_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_child_index()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtStartOfAnchorWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, |
+ 0 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ text_position->GetPositionAtStartOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box1_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_text_offset()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ test_position.reset(text_position->GetPositionAtStartOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box1_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_text_offset()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtEndOfAnchorWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ null_position->GetPositionAtEndOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_TRUE(test_position->IsNullPosition()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtEndOfAnchorWithTreePosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> tree_position( |
+ AXNodePosition::CreateTreePosition(tree_.data().tree_id, root_.id, |
+ 2 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ tree_position->GetPositionAtEndOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(root_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(2, test_position->get_child_index()); |
+ |
+ tree_position.reset(AXNodePosition::CreateTreePosition( |
+ tree_.data().tree_id, root_.id, 1 /* child_index */)); |
+ ASSERT_NE(nullptr, tree_position); |
+ test_position.reset(tree_position->GetPositionAtEndOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(root_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(2, test_position->get_child_index()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPositionAtEndOfAnchorWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, |
+ 6 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ text_position->GetPositionAtEndOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box1_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(6, test_position->get_text_offset()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ test_position.reset(text_position->GetPositionAtEndOfAnchor()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box1_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(6, test_position->get_text_offset()); |
+} |
+ |
+TEST_F(AXTreeTest, GetNextCharacterPositionWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ null_position->GetNextCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_TRUE(test_position->IsNullPosition()); |
+} |
+ |
+TEST_F(AXTreeTest, GetNextCharacterPositionWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, |
+ 4 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ text_position->GetNextCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box1_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(5, test_position->get_text_offset()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ test_position.reset(text_position->GetNextCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(line_break_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_text_offset()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPreviousCharacterPositionWithNullPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> null_position( |
+ AXNodePosition::CreateNullPosition()); |
+ ASSERT_NE(nullptr, null_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ null_position->GetPreviousCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_TRUE(test_position->IsNullPosition()); |
+} |
+ |
+TEST_F(AXTreeTest, GetPreviousCharacterPositionWithTextPosition) { |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> text_position( |
+ AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box2_.id, |
+ 5 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ std::unique_ptr<AXPosition<AXNodePosition, AXNode>> test_position( |
+ text_position->GetPreviousCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(inline_box2_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(4, test_position->get_text_offset()); |
+ |
+ text_position.reset(AXNodePosition::CreateTextPosition( |
+ tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */)); |
+ ASSERT_NE(nullptr, text_position); |
+ test_position.reset(text_position->GetPreviousCharacterPosition()); |
+ EXPECT_NE(nullptr, test_position); |
+ EXPECT_EQ(line_break_.id, test_position->get_anchor_id()); |
+ EXPECT_EQ(0, test_position->get_text_offset()); |
+} |
+ |
+} // namespace ui |