Home | History | Annotate | Download | only in parser
      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