Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Unified Diff: ui/accessibility/ax_tree_serializer_unittest.cc

Issue 90853002: Make tree serialization more robust and add more unit tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/accessibility/ax_tree_serializer_unittest.cc
diff --git a/ui/accessibility/ax_tree_serializer_unittest.cc b/ui/accessibility/ax_tree_serializer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..440a367455065a797406fccd4ff08375e6eb6bdb
--- /dev/null
+++ b/ui/accessibility/ax_tree_serializer_unittest.cc
@@ -0,0 +1,177 @@
+// Copyright 2013 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 "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_node.h"
+#include "ui/accessibility/ax_serializable_tree.h"
+#include "ui/accessibility/ax_tree.h"
+#include "ui/accessibility/ax_tree_serializer.h"
+
+namespace ui {
+
+// The framework for these tests is that each test sets up |treedata1_|
aboxhall 2013/12/02 17:18:08 treedata0_ and treedata1_
dmazzoni 2013/12/03 08:35:04 Done.
+// and |treedata2_| and then calls GetTreeSerializer, which creates a
+// serializer for a tree that's initially in state |treedata1_|, but then
+// changes to state |treedata2_|. This allows each test to check the
+// updates created by AXTreeSerializer or unit-test its private
+// member functions.
+class AXTreeSerializerTest : public testing::Test {
+ public:
+ AXTreeSerializerTest() {}
+ virtual ~AXTreeSerializerTest() {}
+
+ protected:
+ void CreateTreeSerializer();
+
+ AXTreeUpdate treedata0_;
+ AXTreeUpdate treedata1_;
+ scoped_ptr<AXSerializableTree> tree0_;
+ scoped_ptr<AXSerializableTree> tree1_;
+ scoped_ptr<AXTreeSource<AXNode> > tree0_source_;
+ scoped_ptr<AXTreeSource<AXNode> > tree1_source_;
+ scoped_ptr<AXTreeSerializer<AXNode> > serializer_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AXTreeSerializerTest);
+};
+
+void AXTreeSerializerTest::CreateTreeSerializer() {
+ if (serializer_)
+ return;
+
+ tree0_.reset(new AXSerializableTree(treedata0_));
+ tree1_.reset(new AXSerializableTree(treedata1_));
+
+ // Serialize tree0.
aboxhall 2013/12/02 17:18:08 This comment might need a bit more information - i
dmazzoni 2013/12/03 08:35:04 Yes, I tried to clarify that.
+ tree0_source_.reset(tree0_->CreateTreeSource());
+ serializer_.reset(new AXTreeSerializer<AXNode>(tree0_source_.get()));
+ AXTreeUpdate update0;
+ serializer_->SerializeChanges(tree0_->GetRoot(), &update0);
+
+ // Pretend that tree0_ turned into tree1_.
+ tree1_source_.reset(tree1_->CreateTreeSource());
+ serializer_->ChangeTreeSourceForTesting(tree1_source_.get());
+}
+
+// In this test, one child is added to the root. Only the root and
+// new child should be added.
+TEST_F(AXTreeSerializerTest, UpdateContainsOnlyChangedNodes) {
+ // (1 (2 3))
+ treedata0_.nodes.resize(3);
+ treedata0_.nodes[0].id = 1;
+ treedata0_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata0_.nodes[0].child_ids.push_back(2);
+ treedata0_.nodes[0].child_ids.push_back(3);
+ treedata0_.nodes[1].id = 2;
+ treedata0_.nodes[2].id = 3;
+
+ // (1 (4 2 3))
+ treedata1_.nodes.resize(4);
+ treedata1_.nodes[0].id = 1;
+ treedata1_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata1_.nodes[0].child_ids.push_back(4);
+ treedata1_.nodes[0].child_ids.push_back(2);
+ treedata1_.nodes[0].child_ids.push_back(3);
+ treedata1_.nodes[1].id = 2;
+ treedata1_.nodes[2].id = 3;
+ treedata1_.nodes[3].id = 4;
+
+ CreateTreeSerializer();
+ AXTreeUpdate update;
+ serializer_->SerializeChanges(tree1_->GetFromId(1), &update);
+
+ // The update should only touch nodes 1 and 4 - nodes 2 and 3 are unchanged
+ // and shouldn't be affected.
+ EXPECT_EQ(0, update.node_id_to_clear);
+ ASSERT_EQ(static_cast<size_t>(2), update.nodes.size());
+ EXPECT_EQ(1, update.nodes[0].id);
+ EXPECT_EQ(4, update.nodes[1].id);
+}
+
+// When the root changes, the whole tree is updated, even if some of it
+// is unaffected.
+TEST_F(AXTreeSerializerTest, NewRootUpdatesEntireTree) {
+ // (1 (2 (3 (4))))
+ treedata0_.nodes.resize(4);
+ treedata0_.nodes[0].id = 1;
+ treedata0_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata0_.nodes[0].child_ids.push_back(2);
+ treedata0_.nodes[1].id = 2;
+ treedata0_.nodes[1].child_ids.push_back(3);
+ treedata0_.nodes[2].id = 3;
+ treedata0_.nodes[2].child_ids.push_back(4);
+ treedata0_.nodes[3].id = 4;
+
+ // (5 (2 (3 (4))))
+ treedata1_.nodes.resize(4);
+ treedata1_.nodes[0].id = 5;
+ treedata1_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata1_.nodes[0].child_ids.push_back(2);
+ treedata1_.nodes[1].id = 2;
+ treedata1_.nodes[1].child_ids.push_back(3);
+ treedata1_.nodes[2].id = 3;
+ treedata1_.nodes[2].child_ids.push_back(4);
+ treedata1_.nodes[3].id = 4;
+
+ CreateTreeSerializer();
+ AXTreeUpdate update;
+ serializer_->SerializeChanges(tree1_->GetFromId(4), &update);
+
+ // The update should delete the subtree rooted at node id=1, and
+ // then include all four nodes in the update, even though the
+ // subtree rooted at id=2 didn't actually change.
+ EXPECT_EQ(1, update.node_id_to_clear);
+ ASSERT_EQ(static_cast<size_t>(4), update.nodes.size());
+ EXPECT_EQ(5, update.nodes[0].id);
+ EXPECT_EQ(2, update.nodes[1].id);
+ EXPECT_EQ(3, update.nodes[2].id);
+ EXPECT_EQ(4, update.nodes[3].id);
+}
+
+// When a node is reparented, the subtree including both the old parent
+// and new parent of the reparented node must be deleted and recreated.
+TEST_F(AXTreeSerializerTest, ReparentingUpdatesSubtree) {
+ // (1 (2 (3 (4) 5)))
+ treedata0_.nodes.resize(5);
+ treedata0_.nodes[0].id = 1;
+ treedata0_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata0_.nodes[0].child_ids.push_back(2);
+ treedata0_.nodes[1].id = 2;
+ treedata0_.nodes[1].child_ids.push_back(3);
+ treedata0_.nodes[1].child_ids.push_back(5);
+ treedata0_.nodes[2].id = 3;
+ treedata0_.nodes[2].child_ids.push_back(4);
+ treedata0_.nodes[3].id = 4;
+ treedata0_.nodes[4].id = 5;
+
+ // (1 (2 (3 (4 (5)))))
aboxhall 2013/12/02 17:18:08 Perhaps explicitly comment which node has been rep
dmazzoni 2013/12/03 08:35:04 Done.
+ treedata1_.nodes.resize(5);
+ treedata1_.nodes[0].id = 1;
+ treedata1_.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
+ treedata1_.nodes[0].child_ids.push_back(2);
+ treedata1_.nodes[1].id = 2;
+ treedata1_.nodes[1].child_ids.push_back(3);
+ treedata1_.nodes[2].id = 3;
+ treedata1_.nodes[2].child_ids.push_back(4);
+ treedata1_.nodes[3].id = 4;
+ treedata1_.nodes[3].child_ids.push_back(5);
+ treedata1_.nodes[4].id = 5;
+
+ CreateTreeSerializer();
+ AXTreeUpdate update;
+ serializer_->SerializeChanges(tree1_->GetFromId(4), &update);
+
+ // The update should delete the subtree rooted at node id=2, and
+ // then include nodes 2...5.
+ EXPECT_EQ(2, update.node_id_to_clear);
+ ASSERT_EQ(static_cast<size_t>(4), update.nodes.size());
+ EXPECT_EQ(2, update.nodes[0].id);
+ EXPECT_EQ(3, update.nodes[1].id);
+ EXPECT_EQ(4, update.nodes[2].id);
+ EXPECT_EQ(5, update.nodes[3].id);
+}
+
+} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698