1 // Copyright 2017 PDFium 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 "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
6 
7 #include <memory>
8 #include <vector>
9 
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/test_support.h"
12 #include "third_party/base/ptr_util.h"
13 
14 class CXFA_NodeIteratorTemplateTest : public testing::Test {
15  public:
16   class Node {
17    public:
18     class Strategy {
19      public:
GetFirstChild(Node * pNode)20       static Node* GetFirstChild(Node* pNode) {
21         return pNode && !pNode->children_.empty() ? pNode->children_.front()
22                                                   : nullptr;
23       }
GetNextSibling(Node * pNode)24       static Node* GetNextSibling(Node* pNode) {
25         return pNode ? pNode->next_sibling_ : nullptr;
26       }
GetParent(Node * pNode)27       static Node* GetParent(Node* pNode) {
28         return pNode ? pNode->parent_ : nullptr;
29       }
30     };
31 
Node(Node * parent)32     explicit Node(Node* parent) : parent_(parent), next_sibling_(nullptr) {
33       if (parent) {
34         if (!parent->children_.empty())
35           parent->children_.back()->next_sibling_ = this;
36         parent->children_.push_back(this);
37       }
38     }
39 
40    private:
41     Node* parent_;
42     Node* next_sibling_;
43     std::vector<Node*> children_;
44   };
45 
46   using Iterator = CXFA_NodeIteratorTemplate<Node, Node::Strategy>;
47 
48   // Builds a tree along the lines of:
49   //
50   //   root
51   //   |
52   //   child1--child2
53   //            |
54   //            child3------------child7--child9
55   //            |                 |
56   //            child4--child6    child8
57   //            |
58   //            child5
59   //
SetUp()60   void SetUp() override {
61     root_ = pdfium::MakeUnique<Node>(nullptr);
62     child1_ = pdfium::MakeUnique<Node>(root_.get());
63     child2_ = pdfium::MakeUnique<Node>(root_.get());
64     child3_ = pdfium::MakeUnique<Node>(child2_.get());
65     child4_ = pdfium::MakeUnique<Node>(child3_.get());
66     child5_ = pdfium::MakeUnique<Node>(child4_.get());
67     child6_ = pdfium::MakeUnique<Node>(child3_.get());
68     child7_ = pdfium::MakeUnique<Node>(child2_.get());
69     child8_ = pdfium::MakeUnique<Node>(child7_.get());
70     child9_ = pdfium::MakeUnique<Node>(child2_.get());
71   }
72 
root() const73   Node* root() const { return root_.get(); }
child1() const74   Node* child1() const { return child1_.get(); }
child2() const75   Node* child2() const { return child2_.get(); }
child3() const76   Node* child3() const { return child3_.get(); }
child4() const77   Node* child4() const { return child4_.get(); }
child5() const78   Node* child5() const { return child5_.get(); }
child6() const79   Node* child6() const { return child6_.get(); }
child7() const80   Node* child7() const { return child7_.get(); }
child8() const81   Node* child8() const { return child8_.get(); }
child9() const82   Node* child9() const { return child9_.get(); }
83 
84  protected:
85   std::unique_ptr<Node> root_;
86   std::unique_ptr<Node> child1_;
87   std::unique_ptr<Node> child2_;
88   std::unique_ptr<Node> child3_;
89   std::unique_ptr<Node> child4_;
90   std::unique_ptr<Node> child5_;
91   std::unique_ptr<Node> child6_;
92   std::unique_ptr<Node> child7_;
93   std::unique_ptr<Node> child8_;
94   std::unique_ptr<Node> child9_;
95 };
96 
TEST_F(CXFA_NodeIteratorTemplateTest,Empty)97 TEST_F(CXFA_NodeIteratorTemplateTest, Empty) {
98   Iterator iter(nullptr);
99   EXPECT_EQ(nullptr, iter.GetRoot());
100   EXPECT_EQ(nullptr, iter.GetCurrent());
101   EXPECT_EQ(nullptr, iter.MoveToNext());
102   EXPECT_EQ(nullptr, iter.MoveToPrev());
103   EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
104 }
105 
TEST_F(CXFA_NodeIteratorTemplateTest,Root)106 TEST_F(CXFA_NodeIteratorTemplateTest, Root) {
107   Iterator iter(root());
108   EXPECT_EQ(root(), iter.GetRoot());
109   EXPECT_EQ(root(), iter.GetCurrent());
110 }
111 
TEST_F(CXFA_NodeIteratorTemplateTest,Current)112 TEST_F(CXFA_NodeIteratorTemplateTest, Current) {
113   Iterator iter(root());
114   iter.SetCurrent(child1());
115   EXPECT_EQ(root(), iter.GetRoot());
116   EXPECT_EQ(child1(), iter.GetCurrent());
117 }
118 
TEST_F(CXFA_NodeIteratorTemplateTest,CurrentOutsideRootDisallowed)119 TEST_F(CXFA_NodeIteratorTemplateTest, CurrentOutsideRootDisallowed) {
120   Iterator iter(child1());
121   iter.SetCurrent(root());
122   EXPECT_EQ(child1(), iter.GetRoot());
123   EXPECT_EQ(nullptr, iter.GetCurrent());
124 }
125 
TEST_F(CXFA_NodeIteratorTemplateTest,CurrentNull)126 TEST_F(CXFA_NodeIteratorTemplateTest, CurrentNull) {
127   Iterator iter(root());
128   EXPECT_EQ(child1(), iter.MoveToNext());
129 
130   iter.SetCurrent(nullptr);
131   EXPECT_EQ(nullptr, iter.GetCurrent());
132 
133   EXPECT_EQ(nullptr, iter.MoveToNext());
134   EXPECT_EQ(nullptr, iter.GetCurrent());
135 }
136 
TEST_F(CXFA_NodeIteratorTemplateTest,MoveToPrev)137 TEST_F(CXFA_NodeIteratorTemplateTest, MoveToPrev) {
138   Iterator iter(root());
139   iter.SetCurrent(child9());
140 
141   EXPECT_EQ(child8(), iter.MoveToPrev());
142   EXPECT_EQ(child8(), iter.GetCurrent());
143 
144   EXPECT_EQ(child7(), iter.MoveToPrev());
145   EXPECT_EQ(child7(), iter.GetCurrent());
146 
147   EXPECT_EQ(child6(), iter.MoveToPrev());
148   EXPECT_EQ(child6(), iter.GetCurrent());
149 
150   EXPECT_EQ(child5(), iter.MoveToPrev());
151   EXPECT_EQ(child5(), iter.GetCurrent());
152 
153   EXPECT_EQ(child4(), iter.MoveToPrev());
154   EXPECT_EQ(child4(), iter.GetCurrent());
155 
156   EXPECT_EQ(child3(), iter.MoveToPrev());
157   EXPECT_EQ(child3(), iter.GetCurrent());
158 
159   EXPECT_EQ(child2(), iter.MoveToPrev());
160   EXPECT_EQ(child2(), iter.GetCurrent());
161 
162   EXPECT_EQ(child1(), iter.MoveToPrev());
163   EXPECT_EQ(child1(), iter.GetCurrent());
164 
165   EXPECT_EQ(root(), iter.MoveToPrev());
166   EXPECT_EQ(root(), iter.GetCurrent());
167 
168   EXPECT_EQ(nullptr, iter.MoveToPrev());
169   EXPECT_EQ(root(), iter.GetCurrent());
170 
171   EXPECT_EQ(nullptr, iter.MoveToPrev());
172   EXPECT_EQ(root(), iter.GetCurrent());
173 }
174 
TEST_F(CXFA_NodeIteratorTemplateTest,MoveToNext)175 TEST_F(CXFA_NodeIteratorTemplateTest, MoveToNext) {
176   Iterator iter(root());
177   iter.SetCurrent(child2());
178 
179   EXPECT_EQ(child3(), iter.MoveToNext());
180   EXPECT_EQ(child3(), iter.GetCurrent());
181 
182   EXPECT_EQ(child4(), iter.MoveToNext());
183   EXPECT_EQ(child4(), iter.GetCurrent());
184 
185   EXPECT_EQ(child5(), iter.MoveToNext());
186   EXPECT_EQ(child5(), iter.GetCurrent());
187 
188   EXPECT_EQ(child6(), iter.MoveToNext());
189   EXPECT_EQ(child6(), iter.GetCurrent());
190 
191   EXPECT_EQ(child7(), iter.MoveToNext());
192   EXPECT_EQ(child7(), iter.GetCurrent());
193 
194   EXPECT_EQ(child8(), iter.MoveToNext());
195   EXPECT_EQ(child8(), iter.GetCurrent());
196 
197   EXPECT_EQ(child9(), iter.MoveToNext());
198   EXPECT_EQ(child9(), iter.GetCurrent());
199 
200   EXPECT_EQ(nullptr, iter.MoveToNext());
201   EXPECT_EQ(nullptr, iter.GetCurrent());
202 
203   EXPECT_EQ(nullptr, iter.MoveToNext());
204   EXPECT_EQ(nullptr, iter.GetCurrent());
205 }
206 
TEST_F(CXFA_NodeIteratorTemplateTest,SkipChildrenAndMoveToNext)207 TEST_F(CXFA_NodeIteratorTemplateTest, SkipChildrenAndMoveToNext) {
208   Iterator iter(root());
209   iter.SetCurrent(child3());
210   EXPECT_EQ(child7(), iter.SkipChildrenAndMoveToNext());
211   EXPECT_EQ(child9(), iter.SkipChildrenAndMoveToNext());
212   EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
213 }
214 
TEST_F(CXFA_NodeIteratorTemplateTest,BackAndForth)215 TEST_F(CXFA_NodeIteratorTemplateTest, BackAndForth) {
216   Iterator iter(root());
217   EXPECT_EQ(child1(), iter.MoveToNext());
218   EXPECT_EQ(child2(), iter.MoveToNext());
219   EXPECT_EQ(child3(), iter.MoveToNext());
220   EXPECT_EQ(child4(), iter.MoveToNext());
221   EXPECT_EQ(child5(), iter.MoveToNext());
222   EXPECT_EQ(child4(), iter.MoveToPrev());
223   EXPECT_EQ(child3(), iter.MoveToPrev());
224   EXPECT_EQ(child2(), iter.MoveToPrev());
225   EXPECT_EQ(child1(), iter.MoveToPrev());
226 }
227 
TEST_F(CXFA_NodeIteratorTemplateTest,NextFromBeforeTheBeginning)228 TEST_F(CXFA_NodeIteratorTemplateTest, NextFromBeforeTheBeginning) {
229   Iterator iter(root());
230   EXPECT_EQ(nullptr, iter.MoveToPrev());
231   EXPECT_EQ(root(), iter.GetCurrent());
232   EXPECT_EQ(child1(), iter.MoveToNext());
233 }
234 
TEST_F(CXFA_NodeIteratorTemplateTest,PrevFromAfterTheEnd)235 TEST_F(CXFA_NodeIteratorTemplateTest, PrevFromAfterTheEnd) {
236   Iterator iter(root());
237   iter.SetCurrent(child9());
238   EXPECT_EQ(nullptr, iter.MoveToNext());
239   EXPECT_EQ(child9(), iter.MoveToPrev());
240 }
241 
TEST_F(CXFA_NodeIteratorTemplateTest,ChildAsRootPrev)242 TEST_F(CXFA_NodeIteratorTemplateTest, ChildAsRootPrev) {
243   Iterator iter(child3());
244   EXPECT_EQ(nullptr, iter.MoveToPrev());
245 
246   iter.SetCurrent(child4());
247   EXPECT_EQ(child3(), iter.MoveToPrev());
248   EXPECT_EQ(nullptr, iter.MoveToPrev());
249 }
250 
TEST_F(CXFA_NodeIteratorTemplateTest,ChildAsRootNext)251 TEST_F(CXFA_NodeIteratorTemplateTest, ChildAsRootNext) {
252   Iterator iter(child3());
253   iter.SetCurrent(child4());
254   EXPECT_EQ(child5(), iter.MoveToNext());
255   EXPECT_EQ(child6(), iter.MoveToNext());
256   EXPECT_EQ(nullptr, iter.MoveToNext());
257 }
258