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