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