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