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: 20 static Node* GetFirstChild(Node* pNode) { 21 return pNode && !pNode->children_.empty() ? pNode->children_.front() 22 : nullptr; 23 } 24 static Node* GetNextSibling(Node* pNode) { 25 return pNode ? pNode->next_sibling_ : nullptr; 26 } 27 static Node* GetParent(Node* pNode) { 28 return pNode ? pNode->parent_ : nullptr; 29 } 30 }; 31 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 // 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 73 Node* root() const { return root_.get(); } 74 Node* child1() const { return child1_.get(); } 75 Node* child2() const { return child2_.get(); } 76 Node* child3() const { return child3_.get(); } 77 Node* child4() const { return child4_.get(); } 78 Node* child5() const { return child5_.get(); } 79 Node* child6() const { return child6_.get(); } 80 Node* child7() const { return child7_.get(); } 81 Node* child8() const { return child8_.get(); } 82 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 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 106 TEST_F(CXFA_NodeIteratorTemplateTest, Root) { 107 Iterator iter(root()); 108 EXPECT_EQ(root(), iter.GetRoot()); 109 EXPECT_EQ(root(), iter.GetCurrent()); 110 } 111 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 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 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 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 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 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 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 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 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 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 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