Chromium Code Reviews| 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 |