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.
4 
5 #include "ui/accessibility/ax_tree_serializer.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "base/macros.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "testing/gmock/include/gmock/gmock-matchers.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/accessibility/ax_common.h"
17 #include "ui/accessibility/ax_node.h"
18 #include "ui/accessibility/ax_serializable_tree.h"
19 
20 using testing::UnorderedElementsAre;
21 
22 namespace ui {
23 
24 using BasicAXTreeSerializer =
25     AXTreeSerializer<const AXNode*, AXNodeData, AXTreeData>;
26 
27 // The framework for these tests is that each test sets up |treedata0_|
28 // and |treedata1_| and then calls GetTreeSerializer, which creates a
29 // serializer for a tree that's initially in state |treedata0_|, but then
30 // changes to state |treedata1_|. This allows each test to check the
31 // updates created by AXTreeSerializer or unit-test its private
32 // member functions.
33 class AXTreeSerializerTest : public testing::Test {
34  public:
AXTreeSerializerTest()35   AXTreeSerializerTest() {}
~AXTreeSerializerTest()36   ~AXTreeSerializerTest() override {}
37 
38  protected:
39   void CreateTreeSerializer();
40 
41   AXTreeUpdate treedata0_;
42   AXTreeUpdate treedata1_;
43   std::unique_ptr<AXSerializableTree> tree0_;
44   std::unique_ptr<AXSerializableTree> tree1_;
45   std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
46       tree0_source_;
47   std::unique_ptr<AXTreeSource<const AXNode*, AXNodeData, AXTreeData>>
48       tree1_source_;
49   std::unique_ptr<BasicAXTreeSerializer> serializer_;
50 
51  private:
52   DISALLOW_COPY_AND_ASSIGN(AXTreeSerializerTest);
53 };
54 
CreateTreeSerializer()55 void AXTreeSerializerTest::CreateTreeSerializer() {
56   if (serializer_)
57     return;
58 
59   tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
60   tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
61 
62   // Serialize tree0 so that AXTreeSerializer thinks that its client
63   // is totally in sync.
64   tree0_source_.reset(tree0_->CreateTreeSource());
65   serializer_ = std::make_unique<BasicAXTreeSerializer>(tree0_source_.get());
66   AXTreeUpdate unused_update;
67   ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
68 
69   // Pretend that tree0_ turned into tree1_. The next call to
70   // AXTreeSerializer will force it to consider these changes to
71   // the tree and send them as part of the next update.
72   tree1_source_.reset(tree1_->CreateTreeSource());
73   serializer_->ChangeTreeSourceForTesting(tree1_source_.get());
74 }
75 
76 // In this test, one child is added to the root. Only the root and
77 // new child should be added.
TEST_F(AXTreeSerializerTest,UpdateContainsOnlyChangedNodes)78 TEST_F(AXTreeSerializerTest, UpdateContainsOnlyChangedNodes) {
79   // (1 (2 3))
80   treedata0_.root_id = 1;
81   treedata0_.nodes.resize(3);
82   treedata0_.nodes[0].id = 1;
83   treedata0_.nodes[0].child_ids.push_back(2);
84   treedata0_.nodes[0].child_ids.push_back(3);
85   treedata0_.nodes[1].id = 2;
86   treedata0_.nodes[2].id = 3;
87 
88   // (1 (4 2 3))
89   treedata1_.root_id = 1;
90   treedata1_.nodes.resize(4);
91   treedata1_.nodes[0].id = 1;
92   treedata1_.nodes[0].child_ids.push_back(4);
93   treedata1_.nodes[0].child_ids.push_back(2);
94   treedata1_.nodes[0].child_ids.push_back(3);
95   treedata1_.nodes[1].id = 2;
96   treedata1_.nodes[2].id = 3;
97   treedata1_.nodes[3].id = 4;
98 
99   CreateTreeSerializer();
100   AXTreeUpdate update;
101   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(1), &update));
102 
103   // The update should only touch nodes 1 and 4 - nodes 2 and 3 are unchanged
104   // and shouldn't be affected.
105   EXPECT_EQ(0, update.node_id_to_clear);
106   ASSERT_EQ(2u, update.nodes.size());
107   EXPECT_EQ(1, update.nodes[0].id);
108   EXPECT_EQ(4, update.nodes[1].id);
109 }
110 
111 // When the root changes, the whole tree is updated, even if some of it
112 // is unaffected.
TEST_F(AXTreeSerializerTest,NewRootUpdatesEntireTree)113 TEST_F(AXTreeSerializerTest, NewRootUpdatesEntireTree) {
114   // (1 (2 (3 (4))))
115   treedata0_.root_id = 1;
116   treedata0_.nodes.resize(4);
117   treedata0_.nodes[0].id = 1;
118   treedata0_.nodes[0].child_ids.push_back(2);
119   treedata0_.nodes[1].id = 2;
120   treedata0_.nodes[1].child_ids.push_back(3);
121   treedata0_.nodes[2].id = 3;
122   treedata0_.nodes[2].child_ids.push_back(4);
123   treedata0_.nodes[3].id = 4;
124 
125   // (5 (2 (3 (4))))
126   treedata1_.root_id = 5;
127   treedata1_.nodes.resize(4);
128   treedata1_.nodes[0].id = 5;
129   treedata1_.nodes[0].child_ids.push_back(2);
130   treedata1_.nodes[1].id = 2;
131   treedata1_.nodes[1].child_ids.push_back(3);
132   treedata1_.nodes[2].id = 3;
133   treedata1_.nodes[2].child_ids.push_back(4);
134   treedata1_.nodes[3].id = 4;
135 
136   CreateTreeSerializer();
137   AXTreeUpdate update;
138   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
139 
140   // The update should delete the subtree rooted at node id=1, and
141   // then include all four nodes in the update, even though the
142   // subtree rooted at id=2 didn't actually change.
143   EXPECT_EQ(1, update.node_id_to_clear);
144   ASSERT_EQ(4u, update.nodes.size());
145   EXPECT_EQ(5, update.nodes[0].id);
146   EXPECT_EQ(2, update.nodes[1].id);
147   EXPECT_EQ(3, update.nodes[2].id);
148   EXPECT_EQ(4, update.nodes[3].id);
149 }
150 
151 // When a node is reparented, the subtree including both the old parent
152 // and new parent of the reparented node must be deleted and recreated.
TEST_F(AXTreeSerializerTest,ReparentingUpdatesSubtree)153 TEST_F(AXTreeSerializerTest, ReparentingUpdatesSubtree) {
154   // (1 (2 (3 (4) 5)))
155   treedata0_.root_id = 1;
156   treedata0_.nodes.resize(5);
157   treedata0_.nodes[0].id = 1;
158   treedata0_.nodes[0].child_ids.push_back(2);
159   treedata0_.nodes[1].id = 2;
160   treedata0_.nodes[1].child_ids.push_back(3);
161   treedata0_.nodes[1].child_ids.push_back(5);
162   treedata0_.nodes[2].id = 3;
163   treedata0_.nodes[2].child_ids.push_back(4);
164   treedata0_.nodes[3].id = 4;
165   treedata0_.nodes[4].id = 5;
166 
167   // Node 5 has been reparented from being a child of node 2,
168   // to a child of node 4.
169   // (1 (2 (3 (4 (5)))))
170   treedata1_.root_id = 1;
171   treedata1_.nodes.resize(5);
172   treedata1_.nodes[0].id = 1;
173   treedata1_.nodes[0].child_ids.push_back(2);
174   treedata1_.nodes[1].id = 2;
175   treedata1_.nodes[1].child_ids.push_back(3);
176   treedata1_.nodes[2].id = 3;
177   treedata1_.nodes[2].child_ids.push_back(4);
178   treedata1_.nodes[3].id = 4;
179   treedata1_.nodes[3].child_ids.push_back(5);
180   treedata1_.nodes[4].id = 5;
181 
182   CreateTreeSerializer();
183   AXTreeUpdate update;
184   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
185 
186   // The update should unserialize without errors.
187   AXTree dst_tree(treedata0_);
188   EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
189 
190   // The update should delete the subtree rooted at node id=2, and
191   // then include nodes 2...5.
192   EXPECT_EQ(2, update.node_id_to_clear);
193   ASSERT_EQ(4u, update.nodes.size());
194   EXPECT_EQ(2, update.nodes[0].id);
195   EXPECT_EQ(3, update.nodes[1].id);
196   EXPECT_EQ(4, update.nodes[2].id);
197   EXPECT_EQ(5, update.nodes[3].id);
198 }
199 
200 // Similar to ReparentingUpdatesSubtree, except that InvalidateSubtree is
201 // called on id=1 - we need to make sure that the reparenting is still
202 // detected.
TEST_F(AXTreeSerializerTest,ReparentingWithInvalidationUpdatesSubtree)203 TEST_F(AXTreeSerializerTest, ReparentingWithInvalidationUpdatesSubtree) {
204   // (1 (2 (3 (4 (5)))))
205   treedata0_.root_id = 1;
206   treedata0_.nodes.resize(5);
207   treedata0_.nodes[0].id = 1;
208   treedata0_.nodes[0].child_ids.push_back(2);
209   treedata0_.nodes[1].id = 2;
210   treedata0_.nodes[1].child_ids.push_back(3);
211   treedata0_.nodes[2].id = 3;
212   treedata0_.nodes[2].child_ids.push_back(4);
213   treedata0_.nodes[3].id = 4;
214   treedata0_.nodes[3].child_ids.push_back(5);
215   treedata0_.nodes[4].id = 5;
216 
217   // Node 5 has been reparented from being a child of node 4,
218   // to a child of node 2.
219   // (1 (2 (3 (4) 5)))
220   treedata1_.root_id = 1;
221   treedata1_.nodes.resize(5);
222   treedata1_.nodes[0].id = 1;
223   treedata1_.nodes[0].child_ids.push_back(2);
224   treedata1_.nodes[1].id = 2;
225   treedata1_.nodes[1].child_ids.push_back(3);
226   treedata1_.nodes[1].child_ids.push_back(5);
227   treedata1_.nodes[2].id = 3;
228   treedata1_.nodes[2].child_ids.push_back(4);
229   treedata1_.nodes[3].id = 4;
230   treedata1_.nodes[4].id = 5;
231 
232   CreateTreeSerializer();
233   AXTreeUpdate update;
234   serializer_->InvalidateSubtree(tree1_->GetFromId(1));
235   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
236 
237   // The update should unserialize without errors.
238   AXTree dst_tree(treedata0_);
239   EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
240 }
241 
242 // A variant of AXTreeSource that returns true for IsValid() for one
243 // particular id.
244 class AXTreeSourceWithInvalidId
245     : public AXTreeSource<const AXNode*, AXNodeData, AXTreeData> {
246  public:
AXTreeSourceWithInvalidId(AXTree * tree,int invalid_id)247   AXTreeSourceWithInvalidId(AXTree* tree, int invalid_id)
248       : tree_(tree),
249         invalid_id_(invalid_id) {}
~AXTreeSourceWithInvalidId()250   ~AXTreeSourceWithInvalidId() override {}
251 
252   // AXTreeSource implementation.
GetTreeData(AXTreeData * data) const253   bool GetTreeData(AXTreeData* data) const override {
254     *data = AXTreeData();
255     return true;
256   }
GetRoot() const257   AXNode* GetRoot() const override { return tree_->root(); }
GetFromId(int32_t id) const258   AXNode* GetFromId(int32_t id) const override { return tree_->GetFromId(id); }
GetId(const AXNode * node) const259   int32_t GetId(const AXNode* node) const override { return node->id(); }
GetChildren(const AXNode * node,std::vector<const AXNode * > * out_children) const260   void GetChildren(const AXNode* node,
261                    std::vector<const AXNode*>* out_children) const override {
262     *out_children = std::vector<const AXNode*>(node->children().cbegin(),
263                                                node->children().cend());
264   }
GetParent(const AXNode * node) const265   AXNode* GetParent(const AXNode* node) const override {
266     return node->parent();
267   }
IsIgnored(const AXNode * node) const268   bool IsIgnored(const AXNode* node) const override {
269     return node->IsIgnored();
270   }
IsValid(const AXNode * node) const271   bool IsValid(const AXNode* node) const override {
272     return node != nullptr && node->id() != invalid_id_;
273   }
IsEqual(const AXNode * node1,const AXNode * node2) const274   bool IsEqual(const AXNode* node1, const AXNode* node2) const override {
275     return node1 == node2;
276   }
GetNull() const277   const AXNode* GetNull() const override { return nullptr; }
SerializeNode(const AXNode * node,AXNodeData * out_data) const278   void SerializeNode(const AXNode* node, AXNodeData* out_data) const override {
279     *out_data = node->data();
280     if (node->id() == invalid_id_)
281       out_data->id = -1;
282   }
283 
284  private:
285   AXTree* tree_;
286   int invalid_id_;
287 
288   DISALLOW_COPY_AND_ASSIGN(AXTreeSourceWithInvalidId);
289 };
290 
291 // Test that the serializer skips invalid children.
TEST(AXTreeSerializerInvalidTest,InvalidChild)292 TEST(AXTreeSerializerInvalidTest, InvalidChild) {
293   // (1 (2 3))
294   AXTreeUpdate treedata;
295   treedata.root_id = 1;
296   treedata.nodes.resize(3);
297   treedata.nodes[0].id = 1;
298   treedata.nodes[0].child_ids.push_back(2);
299   treedata.nodes[0].child_ids.push_back(3);
300   treedata.nodes[1].id = 2;
301   treedata.nodes[2].id = 3;
302 
303   AXTree tree(treedata);
304   AXTreeSourceWithInvalidId source(&tree, 3);
305 
306   BasicAXTreeSerializer serializer(&source);
307   AXTreeUpdate update;
308   ASSERT_TRUE(serializer.SerializeChanges(tree.root(), &update));
309 
310   ASSERT_EQ(2U, update.nodes.size());
311   EXPECT_EQ(1, update.nodes[0].id);
312   EXPECT_EQ(2, update.nodes[1].id);
313 }
314 
315 // Test that we can set a maximum number of nodes to serialize.
TEST_F(AXTreeSerializerTest,MaximumSerializedNodeCount)316 TEST_F(AXTreeSerializerTest, MaximumSerializedNodeCount) {
317   // (1 (2 (3 4) 5 (6 7)))
318   treedata0_.root_id = 1;
319   treedata0_.nodes.resize(7);
320   treedata0_.nodes[0].id = 1;
321   treedata0_.nodes[0].child_ids.push_back(2);
322   treedata0_.nodes[0].child_ids.push_back(5);
323   treedata0_.nodes[1].id = 2;
324   treedata0_.nodes[1].child_ids.push_back(3);
325   treedata0_.nodes[1].child_ids.push_back(4);
326   treedata0_.nodes[2].id = 3;
327   treedata0_.nodes[3].id = 4;
328   treedata0_.nodes[4].id = 5;
329   treedata0_.nodes[4].child_ids.push_back(6);
330   treedata0_.nodes[4].child_ids.push_back(7);
331   treedata0_.nodes[5].id = 6;
332   treedata0_.nodes[6].id = 7;
333 
334   tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
335   tree0_source_.reset(tree0_->CreateTreeSource());
336   serializer_ = std::make_unique<BasicAXTreeSerializer>(tree0_source_.get());
337   serializer_->set_max_node_count(4);
338   AXTreeUpdate update;
339   ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &update));
340   // It actually serializes 5 nodes, not 4 - to be consistent.
341   // It skips the children of node 5.
342   ASSERT_EQ(5u, update.nodes.size());
343 }
344 
345 #if !defined(AX_FAIL_FAST_BUILD)
346 // If duplicate ids are encountered, it returns an error and the next
347 // update will re-send the entire tree.
TEST_F(AXTreeSerializerTest,DuplicateIdsReturnsErrorAndFlushes)348 TEST_F(AXTreeSerializerTest, DuplicateIdsReturnsErrorAndFlushes) {
349   // (1 (2 (3 (4) 5)))
350   treedata0_.root_id = 1;
351   treedata0_.nodes.resize(5);
352   treedata0_.nodes[0].id = 1;
353   treedata0_.nodes[0].child_ids.push_back(2);
354   treedata0_.nodes[1].id = 2;
355   treedata0_.nodes[1].child_ids.push_back(3);
356   treedata0_.nodes[1].child_ids.push_back(5);
357   treedata0_.nodes[2].id = 3;
358   treedata0_.nodes[2].child_ids.push_back(4);
359   treedata0_.nodes[3].id = 4;
360   treedata0_.nodes[4].id = 5;
361 
362   // (1 (2 (6 (7) 5)))
363   treedata1_.root_id = 1;
364   treedata1_.nodes.resize(5);
365   treedata1_.nodes[0].id = 1;
366   treedata1_.nodes[0].child_ids.push_back(2);
367   treedata1_.nodes[1].id = 2;
368   treedata1_.nodes[1].child_ids.push_back(6);
369   treedata1_.nodes[1].child_ids.push_back(5);
370   treedata1_.nodes[2].id = 6;
371   treedata1_.nodes[2].child_ids.push_back(7);
372   treedata1_.nodes[3].id = 7;
373   treedata1_.nodes[4].id = 5;
374 
375   CreateTreeSerializer();
376 
377   // Do some open-heart surgery on tree1, giving it a duplicate node.
378   // This could not happen with an AXTree, but could happen with
379   // another AXTreeSource if the structure it wraps is buggy. We want to
380   // fail but not crash when that happens.
381   std::vector<AXNode*> node2_children;
382   node2_children.push_back(tree1_->GetFromId(7));
383   node2_children.push_back(tree1_->GetFromId(6));
384   tree1_->GetFromId(2)->SwapChildren(&node2_children);
385 
386   AXTreeUpdate update;
387   ASSERT_FALSE(serializer_->SerializeChanges(tree1_->GetFromId(7), &update));
388 
389   // Swap it back, fixing the tree.
390   tree1_->GetFromId(2)->SwapChildren(&node2_children);
391 
392   // Now try to serialize again. We should get the whole tree because the
393   // previous failed call to SerializeChanges reset it.
394   update = AXTreeUpdate();
395   serializer_->SerializeChanges(tree1_->GetFromId(7), &update);
396   ASSERT_EQ(5u, update.nodes.size());
397 }
398 #endif  // !defined(AX_FAIL_FAST_BUILD)
399 
400 // If a tree serializer is reset, that means it doesn't know about
401 // the state of the client tree anymore. The safest thing to do in
402 // that circumstance is to force the client to clear everything.
TEST_F(AXTreeSerializerTest,ResetUpdatesNodeIdToClear)403 TEST_F(AXTreeSerializerTest, ResetUpdatesNodeIdToClear) {
404   // (1 (2 (3 (4 (5)))))
405   treedata0_.root_id = 1;
406   treedata0_.nodes.resize(5);
407   treedata0_.nodes[0].id = 1;
408   treedata0_.nodes[0].child_ids.push_back(2);
409   treedata0_.nodes[1].id = 2;
410   treedata0_.nodes[1].child_ids.push_back(3);
411   treedata0_.nodes[2].id = 3;
412   treedata0_.nodes[2].child_ids.push_back(4);
413   treedata0_.nodes[3].id = 4;
414   treedata0_.nodes[3].child_ids.push_back(5);
415   treedata0_.nodes[4].id = 5;
416 
417   // Node 5 has been reparented from being a child of node 4,
418   // to a child of node 2.
419   // (1 (2 (3 (4) 5)))
420   treedata1_.root_id = 1;
421   treedata1_.nodes.resize(5);
422   treedata1_.nodes[0].id = 1;
423   treedata1_.nodes[0].child_ids.push_back(2);
424   treedata1_.nodes[1].id = 2;
425   treedata1_.nodes[1].child_ids.push_back(3);
426   treedata1_.nodes[1].child_ids.push_back(5);
427   treedata1_.nodes[2].id = 3;
428   treedata1_.nodes[2].child_ids.push_back(4);
429   treedata1_.nodes[3].id = 4;
430   treedata1_.nodes[4].id = 5;
431 
432   CreateTreeSerializer();
433 
434   serializer_->Reset();
435 
436   AXTreeUpdate update;
437   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
438 
439   // The update should unserialize without errors.
440   AXTree dst_tree(treedata0_);
441   EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
442 }
443 
444 // Ensure that calling Reset doesn't cause any problems if
445 // the root changes.
TEST_F(AXTreeSerializerTest,ResetWorksWithNewRootId)446 TEST_F(AXTreeSerializerTest, ResetWorksWithNewRootId) {
447   // (1 (2))
448   treedata0_.root_id = 1;
449   treedata0_.nodes.resize(2);
450   treedata0_.nodes[0].id = 1;
451   treedata0_.nodes[0].child_ids.push_back(2);
452   treedata0_.nodes[1].id = 2;
453 
454   // (3 (4))
455   treedata1_.root_id = 3;
456   treedata1_.nodes.resize(2);
457   treedata1_.nodes[0].id = 3;
458   treedata1_.nodes[0].child_ids.push_back(4);
459   treedata1_.nodes[1].id = 4;
460 
461   CreateTreeSerializer();
462   serializer_->Reset();
463 
464   AXTreeUpdate update;
465   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->GetFromId(4), &update));
466 
467   // The update should unserialize without errors.
468   AXTree dst_tree(treedata0_);
469   EXPECT_TRUE(dst_tree.Unserialize(update)) << dst_tree.error();
470 }
471 
472 // Wraps an AXTreeSource and provides access to the results of the
473 // SerializerClearedNode callback.
474 class AXTreeSourceTestWrapper
475     : public AXTreeSource<const AXNode*, AXNodeData, AXTreeData> {
476  public:
AXTreeSourceTestWrapper(AXTreeSource<const AXNode *,AXNodeData,AXTreeData> * tree_source)477   explicit AXTreeSourceTestWrapper(
478       AXTreeSource<const AXNode*, AXNodeData, AXTreeData>* tree_source)
479       : tree_source_(tree_source) {}
480   ~AXTreeSourceTestWrapper() override = default;
481 
482   // Override SerializerClearedNode and provide a way to access it.
SerializerClearedNode(int32_t node_id)483   void SerializerClearedNode(int32_t node_id) override {
484     cleared_node_ids_.insert(node_id);
485   }
486 
ClearClearedNodeIds()487   void ClearClearedNodeIds() { cleared_node_ids_.clear(); }
cleared_node_ids()488   std::set<int32_t>& cleared_node_ids() { return cleared_node_ids_; }
489 
490   // The rest of the AXTreeSource implementation just calls through to
491   // tree_source_.
GetTreeData(AXTreeData * data) const492   bool GetTreeData(AXTreeData* data) const override {
493     return tree_source_->GetTreeData(data);
494   }
GetRoot() const495   const AXNode* GetRoot() const override { return tree_source_->GetRoot(); }
GetFromId(int32_t id) const496   const AXNode* GetFromId(int32_t id) const override {
497     return tree_source_->GetFromId(id);
498   }
GetId(const AXNode * node) const499   int32_t GetId(const AXNode* node) const override {
500     return tree_source_->GetId(node);
501   }
GetChildren(const AXNode * node,std::vector<const AXNode * > * out_children) const502   void GetChildren(const AXNode* node,
503                    std::vector<const AXNode*>* out_children) const override {
504     return tree_source_->GetChildren(node, out_children);
505   }
GetParent(const AXNode * node) const506   const AXNode* GetParent(const AXNode* node) const override {
507     return tree_source_->GetParent(node);
508   }
IsIgnored(const AXNode * node) const509   bool IsIgnored(const AXNode* node) const override {
510     return tree_source_->IsIgnored(node);
511   }
IsValid(const AXNode * node) const512   bool IsValid(const AXNode* node) const override {
513     return tree_source_->IsValid(node);
514   }
IsEqual(const AXNode * node1,const AXNode * node2) const515   bool IsEqual(const AXNode* node1, const AXNode* node2) const override {
516     return tree_source_->IsEqual(node1, node2);
517   }
GetNull() const518   const AXNode* GetNull() const override { return tree_source_->GetNull(); }
SerializeNode(const AXNode * node,AXNodeData * out_data) const519   void SerializeNode(const AXNode* node, AXNodeData* out_data) const override {
520     tree_source_->SerializeNode(node, out_data);
521   }
522 
523  private:
524   AXTreeSource<const AXNode*, AXNodeData, AXTreeData>* tree_source_;
525   std::set<int32_t> cleared_node_ids_;
526 };
527 
TEST_F(AXTreeSerializerTest,TestClearedNodesWhenUpdatingRoot)528 TEST_F(AXTreeSerializerTest, TestClearedNodesWhenUpdatingRoot) {
529   // (1 (2 (3 (4))))
530   treedata0_.root_id = 1;
531   treedata0_.nodes.resize(4);
532   treedata0_.nodes[0].id = 1;
533   treedata0_.nodes[0].child_ids.push_back(2);
534   treedata0_.nodes[1].id = 2;
535   treedata0_.nodes[1].child_ids.push_back(3);
536   treedata0_.nodes[2].id = 3;
537   treedata0_.nodes[2].child_ids.push_back(4);
538   treedata0_.nodes[3].id = 4;
539 
540   // (5 (2 (3 (4))))
541   treedata1_.root_id = 5;
542   treedata1_.nodes.resize(4);
543   treedata1_.nodes[0].id = 5;
544   treedata1_.nodes[0].child_ids.push_back(2);
545   treedata1_.nodes[1].id = 2;
546   treedata1_.nodes[1].child_ids.push_back(3);
547   treedata1_.nodes[2].id = 3;
548   treedata1_.nodes[2].child_ids.push_back(4);
549   treedata1_.nodes[3].id = 4;
550 
551   // Similar sequence to CreateTreeSerializer, but using
552   // AXTreeSourceTestWrapper instead.
553   tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
554   tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
555   tree0_source_.reset(tree0_->CreateTreeSource());
556   AXTreeSourceTestWrapper tree0_source_wrapper(tree0_source_.get());
557   serializer_ = std::make_unique<BasicAXTreeSerializer>(&tree0_source_wrapper);
558   AXTreeUpdate unused_update;
559   ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
560   tree1_source_.reset(tree1_->CreateTreeSource());
561   AXTreeSourceTestWrapper tree1_source_wrapper(tree1_source_.get());
562   serializer_->ChangeTreeSourceForTesting(&tree1_source_wrapper);
563   ASSERT_EQ(4U, serializer_->ClientTreeNodeCount());
564 
565   // If we swap out the root, all of the node IDs should have
566   // SerializerClearedNode called on them.
567   tree1_source_wrapper.ClearClearedNodeIds();
568   ASSERT_TRUE(serializer_->SerializeChanges(tree1_->root(), &unused_update));
569   EXPECT_THAT(tree1_source_wrapper.cleared_node_ids(),
570               UnorderedElementsAre(1, 2, 3, 4));
571 
572   // Destroy the serializer first so that the AXTreeSources it points to
573   // don't go out of scope first.
574   serializer_.reset();
575 }
576 
TEST_F(AXTreeSerializerTest,TestClearedNodesWhenUpdatingBranch)577 TEST_F(AXTreeSerializerTest, TestClearedNodesWhenUpdatingBranch) {
578   // (1 (2 (3 (4))))
579   treedata0_.root_id = 1;
580   treedata0_.nodes.resize(4);
581   treedata0_.nodes[0].id = 1;
582   treedata0_.nodes[0].child_ids.push_back(2);
583   treedata0_.nodes[1].id = 2;
584   treedata0_.nodes[1].child_ids.push_back(3);
585   treedata0_.nodes[2].id = 3;
586   treedata0_.nodes[2].child_ids.push_back(4);
587   treedata0_.nodes[3].id = 4;
588 
589   // (1 (2 (5 (6))))
590   treedata1_.root_id = 1;
591   treedata1_.nodes.resize(4);
592   treedata1_.nodes[0].id = 1;
593   treedata1_.nodes[0].child_ids.push_back(2);
594   treedata1_.nodes[1].id = 2;
595   treedata1_.nodes[1].child_ids.push_back(5);
596   treedata1_.nodes[2].id = 5;
597   treedata1_.nodes[2].child_ids.push_back(6);
598   treedata1_.nodes[3].id = 6;
599 
600   // Similar sequence to CreateTreeSerializer, but using
601   // AXTreeSourceTestWrapper instead.
602   tree0_ = std::make_unique<AXSerializableTree>(treedata0_);
603   tree1_ = std::make_unique<AXSerializableTree>(treedata1_);
604   tree0_source_.reset(tree0_->CreateTreeSource());
605   AXTreeSourceTestWrapper tree0_source_wrapper(tree0_source_.get());
606   serializer_ = std::make_unique<BasicAXTreeSerializer>(&tree0_source_wrapper);
607   AXTreeUpdate unused_update;
608   ASSERT_TRUE(serializer_->SerializeChanges(tree0_->root(), &unused_update));
609   tree1_source_.reset(tree1_->CreateTreeSource());
610   AXTreeSourceTestWrapper tree1_source_wrapper(tree1_source_.get());
611   serializer_->ChangeTreeSourceForTesting(&tree1_source_wrapper);
612   ASSERT_EQ(4U, serializer_->ClientTreeNodeCount());
613 
614   // If we replace one branch with another, we should get calls to
615   // SerializerClearedNode with all of the node IDs no longer in the tree.
616   tree1_source_wrapper.ClearClearedNodeIds();
617   ASSERT_TRUE(
618       serializer_->SerializeChanges(tree1_->GetFromId(2), &unused_update));
619   EXPECT_THAT(tree1_source_wrapper.cleared_node_ids(),
620               UnorderedElementsAre(3, 4));
621 
622   // Destroy the serializer first so that the AXTreeSources it points to
623   // don't go out of scope first.
624   serializer_.reset();
625 }
626 
627 }  // namespace ui
628