1 // Copyright 2013 The Chromium 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.
5 #include "base/memory/scoped_ptr.h"
6 #include "base/strings/string_number_conversions.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/accessibility/ax_node.h"
9 #include "ui/accessibility/ax_serializable_tree.h"
10 #include "ui/accessibility/ax_tree.h"
11 #include "ui/accessibility/ax_tree_serializer.h"
15 TEST(AXTreeTest
, SerializeSimpleAXTree
) {
18 root
.role
= AX_ROLE_ROOT_WEB_AREA
;
19 root
.state
= (1 << AX_STATE_FOCUSABLE
) | (1 << AX_STATE_FOCUSED
);
20 root
.location
= gfx::Rect(0, 0, 800, 600);
21 root
.child_ids
.push_back(2);
22 root
.child_ids
.push_back(3);
26 button
.role
= AX_ROLE_BUTTON
;
28 button
.location
= gfx::Rect(20, 20, 200, 30);
32 checkbox
.role
= AX_ROLE_CHECK_BOX
;
34 checkbox
.location
= gfx::Rect(20, 50, 200, 30);
36 AXTreeUpdate initial_state
;
37 initial_state
.nodes
.push_back(root
);
38 initial_state
.nodes
.push_back(button
);
39 initial_state
.nodes
.push_back(checkbox
);
40 AXSerializableTree
src_tree(initial_state
);
42 scoped_ptr
<AXTreeSource
<AXNode
> > tree_source(
43 src_tree
.CreateTreeSource());
44 AXTreeSerializer
<AXNode
> serializer(tree_source
.get());
46 serializer
.SerializeChanges(src_tree
.GetRoot(), &update
);
49 ASSERT_TRUE(dst_tree
.Unserialize(update
));
51 AXNode
* root_node
= dst_tree
.GetRoot();
52 ASSERT_TRUE(root_node
!= NULL
);
53 EXPECT_EQ(root
.id
, root_node
->id());
54 EXPECT_EQ(root
.role
, root_node
->data().role
);
56 ASSERT_EQ(2, root_node
->child_count());
58 AXNode
* button_node
= root_node
->ChildAtIndex(0);
59 EXPECT_EQ(button
.id
, button_node
->id());
60 EXPECT_EQ(button
.role
, button_node
->data().role
);
62 AXNode
* checkbox_node
= root_node
->ChildAtIndex(1);
63 EXPECT_EQ(checkbox
.id
, checkbox_node
->id());
64 EXPECT_EQ(checkbox
.role
, checkbox_node
->data().role
);
67 "id=1 ROOT_WEB_AREA FOCUSABLE FOCUSED (0, 0)-(800, 600) child_ids=2,3\n"
68 " id=2 BUTTON (20, 20)-(200, 30)\n"
69 " id=3 CHECKBOX (20, 50)-(200, 30)\n",
73 TEST(AXTreeTest
, DeleteUnknownSubtreeFails
) {
76 root
.role
= AX_ROLE_ROOT_WEB_AREA
;
78 AXTreeUpdate initial_state
;
79 initial_state
.nodes
.push_back(root
);
80 AXTree
tree(initial_state
);
82 // This should fail because we're asking it to delete
83 // a subtree rooted at id=2, which doesn't exist.
85 update
.node_id_to_clear
= 2;
86 update
.nodes
.resize(1);
87 update
.nodes
[0].id
= 1;
88 update
.nodes
[0].id
= AX_ROLE_ROOT_WEB_AREA
;
89 EXPECT_FALSE(tree
.Unserialize(update
));
90 ASSERT_EQ("Bad node_id_to_clear: 2", tree
.error());
93 TEST(AXTreeTest
, LeaveOrphanedDeletedSubtreeFails
) {
94 AXTreeUpdate initial_state
;
95 initial_state
.nodes
.resize(3);
96 initial_state
.nodes
[0].id
= 1;
97 initial_state
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
98 initial_state
.nodes
[0].child_ids
.push_back(2);
99 initial_state
.nodes
[0].child_ids
.push_back(3);
100 initial_state
.nodes
[1].id
= 2;
101 initial_state
.nodes
[2].id
= 3;
102 AXTree
tree(initial_state
);
104 // This should fail because we delete a subtree rooted at id=2
105 // but never update it.
107 update
.node_id_to_clear
= 2;
108 update
.nodes
.resize(1);
109 update
.nodes
[0].id
= 3;
110 EXPECT_FALSE(tree
.Unserialize(update
));
111 ASSERT_EQ("Nodes left pending by the update: 2", tree
.error());
114 TEST(AXTreeTest
, LeaveOrphanedNewChildFails
) {
115 AXTreeUpdate initial_state
;
116 initial_state
.nodes
.resize(1);
117 initial_state
.nodes
[0].id
= 1;
118 initial_state
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
119 AXTree
tree(initial_state
);
121 // This should fail because we add a new child to the root node
122 // but never update it.
124 update
.nodes
.resize(1);
125 update
.nodes
[0].id
= 1;
126 update
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
127 update
.nodes
[0].child_ids
.push_back(2);
128 EXPECT_FALSE(tree
.Unserialize(update
));
129 ASSERT_EQ("Nodes left pending by the update: 2", tree
.error());
132 TEST(AXTreeTest
, DuplicateChildIdFails
) {
133 AXTreeUpdate initial_state
;
134 initial_state
.nodes
.resize(1);
135 initial_state
.nodes
[0].id
= 1;
136 initial_state
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
137 AXTree
tree(initial_state
);
139 // This should fail because a child id appears twice.
141 update
.nodes
.resize(2);
142 update
.nodes
[0].id
= 1;
143 update
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
144 update
.nodes
[0].child_ids
.push_back(2);
145 update
.nodes
[0].child_ids
.push_back(2);
146 update
.nodes
[1].id
= 2;
147 EXPECT_FALSE(tree
.Unserialize(update
));
148 ASSERT_EQ("Node 1 has duplicate child id 2", tree
.error());
151 TEST(AXTreeTest
, InvalidReparentingFails
) {
152 AXTreeUpdate initial_state
;
153 initial_state
.nodes
.resize(3);
154 initial_state
.nodes
[0].id
= 1;
155 initial_state
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
156 initial_state
.nodes
[0].child_ids
.push_back(2);
157 initial_state
.nodes
[1].id
= 2;
158 initial_state
.nodes
[1].child_ids
.push_back(3);
159 initial_state
.nodes
[2].id
= 3;
161 AXTree
tree(initial_state
);
163 // This should fail because node 3 is reparented from node 2 to node 1
164 // without deleting node 1's subtree first.
166 update
.nodes
.resize(3);
167 update
.nodes
[0].id
= 1;
168 update
.nodes
[0].role
= AX_ROLE_ROOT_WEB_AREA
;
169 update
.nodes
[0].child_ids
.push_back(3);
170 update
.nodes
[0].child_ids
.push_back(2);
171 update
.nodes
[1].id
= 2;
172 update
.nodes
[2].id
= 3;
173 EXPECT_FALSE(tree
.Unserialize(update
));
174 ASSERT_EQ("Node 3 reparented from 2 to 1", tree
.error());