1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/accessibility/ax_node.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/accessibility/ax_serializable_tree.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/accessibility/ax_tree.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/accessibility/ax_tree_serializer.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace ui {
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class FakeAXTreeDelegate : public AXTreeDelegate {
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnNodeWillBeDeleted(AXNode* node) OVERRIDE {
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    deleted_ids_.push_back(node->id());
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnNodeCreated(AXNode* node) OVERRIDE {
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    created_ids_.push_back(node->id());
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnNodeChanged(AXNode* node) OVERRIDE {
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    changed_ids_.push_back(node->id());
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnNodeCreationFinished(AXNode* node) OVERRIDE {
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    creation_finished_ids_.push_back(node->id());
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnNodeChangeFinished(AXNode* node) OVERRIDE {
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    change_finished_ids_.push_back(node->id());
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnRootChanged(AXNode* new_root) OVERRIDE {
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    new_root_ids_.push_back(new_root->id());
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::vector<int32>& deleted_ids() { return deleted_ids_; }
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::vector<int32>& created_ids() { return created_ids_; }
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const std::vector<int32>& creation_finished_ids() {
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return creation_finished_ids_;
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::vector<int32>& new_root_ids() { return new_root_ids_; }
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<int32> deleted_ids_;
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<int32> created_ids_;
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<int32> creation_finished_ids_;
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<int32> changed_ids_;
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<int32> change_finished_ids_;
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<int32> new_root_ids_;
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, SerializeSimpleAXTree) {
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXNodeData root;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root.id = 1;
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root.role = AX_ROLE_ROOT_WEB_AREA;
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.state = (1 << AX_STATE_FOCUSABLE) | (1 << AX_STATE_FOCUSED);
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root.location = gfx::Rect(0, 0, 800, 600);
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root.child_ids.push_back(2);
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root.child_ids.push_back(3);
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXNodeData button;
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.id = 2;
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.role = AX_ROLE_BUTTON;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  button.state = 0;
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  button.location = gfx::Rect(20, 20, 200, 30);
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXNodeData checkbox;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  checkbox.id = 3;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  checkbox.role = AX_ROLE_CHECK_BOX;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  checkbox.state = 0;
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  checkbox.location = gfx::Rect(20, 50, 200, 30);
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXTreeUpdate initial_state;
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  initial_state.nodes.push_back(root);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  initial_state.nodes.push_back(button);
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  initial_state.nodes.push_back(checkbox);
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXSerializableTree src_tree(initial_state);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<AXTreeSource<const AXNode*> > tree_source(
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      src_tree.CreateTreeSource());
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AXTreeSerializer<const AXNode*> serializer(tree_source.get());
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXTreeUpdate update;
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  serializer.SerializeChanges(src_tree.GetRoot(), &update);
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AXTree dst_tree;
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(dst_tree.Unserialize(update));
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const AXNode* root_node = dst_tree.GetRoot();
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(root_node != NULL);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(root.id, root_node->id());
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(root.role, root_node->data().role);
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(2, root_node->child_count());
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const AXNode* button_node = root_node->ChildAtIndex(0);
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(button.id, button_node->id());
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(button.role, button_node->data().role);
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const AXNode* checkbox_node = root_node->ChildAtIndex(1);
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(checkbox.id, checkbox_node->id());
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(checkbox.role, checkbox_node->data().role);
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "id=1 rootWebArea FOCUSABLE FOCUSED (0, 0)-(800, 600) child_ids=2,3\n"
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "  id=2 button (20, 20)-(200, 30)\n"
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  id=3 checkBox (20, 50)-(200, 30)\n",
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      dst_tree.ToString());
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1190529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST(AXTreeTest, SerializeAXTreeUpdate) {
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AXNodeData list;
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.id = 3;
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.role = AX_ROLE_LIST;
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.state = 0;
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.child_ids.push_back(4);
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.child_ids.push_back(5);
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list.child_ids.push_back(6);
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AXNodeData list_item_2;
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_2.id = 5;
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_2.role = AX_ROLE_LIST_ITEM;
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_2.state = 0;
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AXNodeData list_item_3;
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_3.id = 6;
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_3.role = AX_ROLE_LIST_ITEM;
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  list_item_3.state = 0;
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AXNodeData button;
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  button.id = 7;
1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  button.role = AX_ROLE_BUTTON;
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  button.state = 0;
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  AXTreeUpdate update;
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  update.nodes.push_back(list);
1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  update.nodes.push_back(list_item_2);
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  update.nodes.push_back(list_item_3);
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  update.nodes.push_back(button);
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "id=3 list (0, 0)-(0, 0) child_ids=4,5,6\n"
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  id=5 listItem (0, 0)-(0, 0)\n"
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "  id=6 listItem (0, 0)-(0, 0)\n"
1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "id=7 button (0, 0)-(0, 0)\n",
1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      update.ToString());
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, DeleteUnknownSubtreeFails) {
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXNodeData root;
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.id = 1;
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root.role = AX_ROLE_ROOT_WEB_AREA;
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate initial_state;
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes.push_back(root);
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTree tree(initial_state);
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This should fail because we're asking it to delete
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // a subtree rooted at id=2, which doesn't exist.
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate update;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.node_id_to_clear = 2;
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes.resize(1);
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = 1;
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = AX_ROLE_ROOT_WEB_AREA;
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(tree.Unserialize(update));
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("Bad node_id_to_clear: 2", tree.error());
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, LeaveOrphanedDeletedSubtreeFails) {
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate initial_state;
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes.resize(3);
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].id = 1;
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].child_ids.push_back(2);
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].child_ids.push_back(3);
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[1].id = 2;
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[2].id = 3;
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTree tree(initial_state);
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This should fail because we delete a subtree rooted at id=2
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // but never update it.
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate update;
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.node_id_to_clear = 2;
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes.resize(1);
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = 3;
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(tree.Unserialize(update));
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("Nodes left pending by the update: 2", tree.error());
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, LeaveOrphanedNewChildFails) {
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate initial_state;
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes.resize(1);
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].id = 1;
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTree tree(initial_state);
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This should fail because we add a new child to the root node
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // but never update it.
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate update;
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes.resize(1);
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = 1;
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].child_ids.push_back(2);
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(tree.Unserialize(update));
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("Nodes left pending by the update: 2", tree.error());
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, DuplicateChildIdFails) {
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate initial_state;
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes.resize(1);
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].id = 1;
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTree tree(initial_state);
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This should fail because a child id appears twice.
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate update;
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes.resize(2);
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = 1;
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].child_ids.push_back(2);
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].child_ids.push_back(2);
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[1].id = 2;
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(tree.Unserialize(update));
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("Node 1 has duplicate child id 2", tree.error());
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST(AXTreeTest, InvalidReparentingFails) {
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate initial_state;
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes.resize(3);
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].id = 1;
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[0].child_ids.push_back(2);
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[1].id = 2;
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[1].child_ids.push_back(3);
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  initial_state.nodes[2].id = 3;
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTree tree(initial_state);
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This should fail because node 3 is reparented from node 2 to node 1
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // without deleting node 1's subtree first.
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AXTreeUpdate update;
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes.resize(3);
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].id = 1;
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].child_ids.push_back(3);
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[0].child_ids.push_back(2);
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[1].id = 2;
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  update.nodes[2].id = 3;
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(tree.Unserialize(update));
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ("Node 3 reparented from 2 to 1", tree.error());
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(AXTreeTest, TreeDelegateIsCalled) {
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AXTreeUpdate initial_state;
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  initial_state.nodes.resize(1);
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  initial_state.nodes[0].id = 1;
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  initial_state.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AXTree tree(initial_state);
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  AXTreeUpdate update;
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.node_id_to_clear = 1;
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.nodes.resize(2);
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.nodes[0].id = 2;
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.nodes[0].child_ids.push_back(3);
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update.nodes[1].id = 3;
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeAXTreeDelegate fake_delegate;
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  tree.SetDelegate(&fake_delegate);
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(tree.Unserialize(update));
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, fake_delegate.deleted_ids().size());
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, fake_delegate.deleted_ids()[0]);
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(2U, fake_delegate.created_ids().size());
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, fake_delegate.created_ids()[0]);
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, fake_delegate.created_ids()[1]);
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(2U, fake_delegate.creation_finished_ids().size());
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(2, fake_delegate.creation_finished_ids()[0]);
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(3, fake_delegate.creation_finished_ids()[1]);
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, fake_delegate.new_root_ids().size());
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, fake_delegate.new_root_ids()[0]);
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  tree.SetDelegate(NULL);
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace ui
299