blob: 4c7f47bbb1a62b69e74e3b88d8357ae51551a9ba [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "xfa/fxfa/parser/xfa_utils.h"
#include <memory>
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/ptr_util.h"
TEST(XfaUtilsImp, XFA_MapRotation) {
struct TestCase {
int input;
int expected_output;
} TestCases[] = {{-1000000, 80}, {-361, 359}, {-360, 0}, {-359, 1},
{-91, 269}, {-90, 270}, {-89, 271}, {-1, 359},
{0, 0}, {1, 1}, {89, 89}, {90, 90},
{91, 91}, {359, 359}, {360, 0}, {361, 1},
{100000, 280}};
for (size_t i = 0; i < FX_ArraySize(TestCases); ++i) {
EXPECT_EQ(TestCases[i].expected_output,
XFA_MapRotation(TestCases[i].input));
}
}
class XFANodeIteratorTest : public testing::Test {
public:
class Node {
public:
class Strategy {
public:
static Node* GetFirstChild(Node* pNode) {
return pNode && !pNode->children_.empty() ? pNode->children_.front()
: nullptr;
}
static Node* GetNextSibling(Node* pNode) {
return pNode ? pNode->next_sibling_ : nullptr;
}
static Node* GetParent(Node* pNode) {
return pNode ? pNode->parent_ : nullptr;
}
};
explicit Node(Node* parent) : parent_(parent), next_sibling_(nullptr) {
if (parent) {
if (!parent->children_.empty())
parent->children_.back()->next_sibling_ = this;
parent->children_.push_back(this);
}
}
private:
Node* parent_;
Node* next_sibling_;
std::vector<Node*> children_;
};
using Iterator = CXFA_NodeIteratorTemplate<Node, Node::Strategy>;
// Builds a tree along the lines of:
//
// root
// |
// child1--child2
// |
// child3------------child7--child9
// | |
// child4--child6 child8
// |
// child5
//
void SetUp() override {
root_ = pdfium::MakeUnique<Node>(nullptr);
child1_ = pdfium::MakeUnique<Node>(root_.get());
child2_ = pdfium::MakeUnique<Node>(root_.get());
child3_ = pdfium::MakeUnique<Node>(child2_.get());
child4_ = pdfium::MakeUnique<Node>(child3_.get());
child5_ = pdfium::MakeUnique<Node>(child4_.get());
child6_ = pdfium::MakeUnique<Node>(child3_.get());
child7_ = pdfium::MakeUnique<Node>(child2_.get());
child8_ = pdfium::MakeUnique<Node>(child7_.get());
child9_ = pdfium::MakeUnique<Node>(child2_.get());
}
Node* root() const { return root_.get(); }
Node* child1() const { return child1_.get(); }
Node* child2() const { return child2_.get(); }
Node* child3() const { return child3_.get(); }
Node* child4() const { return child4_.get(); }
Node* child5() const { return child5_.get(); }
Node* child6() const { return child6_.get(); }
Node* child7() const { return child7_.get(); }
Node* child8() const { return child8_.get(); }
Node* child9() const { return child9_.get(); }
protected:
std::unique_ptr<Node> root_;
std::unique_ptr<Node> child1_;
std::unique_ptr<Node> child2_;
std::unique_ptr<Node> child3_;
std::unique_ptr<Node> child4_;
std::unique_ptr<Node> child5_;
std::unique_ptr<Node> child6_;
std::unique_ptr<Node> child7_;
std::unique_ptr<Node> child8_;
std::unique_ptr<Node> child9_;
};
TEST_F(XFANodeIteratorTest, Empty) {
Iterator iter(nullptr);
EXPECT_EQ(nullptr, iter.GetRoot());
EXPECT_EQ(nullptr, iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToNext());
EXPECT_EQ(nullptr, iter.MoveToPrev());
EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
}
TEST_F(XFANodeIteratorTest, Root) {
Iterator iter(root());
EXPECT_EQ(root(), iter.GetRoot());
EXPECT_EQ(root(), iter.GetCurrent());
EXPECT_EQ(root(), iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, Current) {
Iterator iter(root());
iter.SetCurrent(child1());
EXPECT_EQ(root(), iter.GetRoot());
EXPECT_EQ(child1(), iter.GetCurrent());
EXPECT_EQ(child1(), iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, CurrentOutsideRoot) {
Iterator iter(child1());
iter.SetCurrent(root());
EXPECT_EQ(child1(), iter.GetRoot());
EXPECT_EQ(nullptr, iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, CurrentNull) {
Iterator iter(root());
EXPECT_EQ(child1(), iter.MoveToNext());
iter.SetCurrent(nullptr);
EXPECT_EQ(nullptr, iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToNext());
EXPECT_EQ(nullptr, iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, MoveToPrev) {
Iterator iter(root());
iter.SetCurrent(child8());
EXPECT_EQ(child7(), iter.MoveToPrev());
EXPECT_EQ(child7(), iter.GetCurrent());
EXPECT_EQ(child6(), iter.MoveToPrev());
EXPECT_EQ(child6(), iter.GetCurrent());
EXPECT_EQ(child5(), iter.MoveToPrev());
EXPECT_EQ(child5(), iter.GetCurrent());
EXPECT_EQ(child4(), iter.MoveToPrev());
EXPECT_EQ(child4(), iter.GetCurrent());
EXPECT_EQ(child3(), iter.MoveToPrev());
EXPECT_EQ(child3(), iter.GetCurrent());
EXPECT_EQ(child2(), iter.MoveToPrev());
EXPECT_EQ(child2(), iter.GetCurrent());
EXPECT_EQ(child1(), iter.MoveToPrev());
EXPECT_EQ(child1(), iter.GetCurrent());
EXPECT_EQ(root(), iter.MoveToPrev());
EXPECT_EQ(root(), iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToPrev());
EXPECT_EQ(root(), iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToPrev());
EXPECT_EQ(root(), iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, MoveToNext) {
Iterator iter(root());
iter.SetCurrent(child2());
EXPECT_EQ(child3(), iter.MoveToNext());
EXPECT_EQ(child3(), iter.GetCurrent());
EXPECT_EQ(child4(), iter.MoveToNext());
EXPECT_EQ(child4(), iter.GetCurrent());
EXPECT_EQ(child5(), iter.MoveToNext());
EXPECT_EQ(child5(), iter.GetCurrent());
EXPECT_EQ(child6(), iter.MoveToNext());
EXPECT_EQ(child6(), iter.GetCurrent());
EXPECT_EQ(child7(), iter.MoveToNext());
EXPECT_EQ(child7(), iter.GetCurrent());
EXPECT_EQ(child8(), iter.MoveToNext());
EXPECT_EQ(child8(), iter.GetCurrent());
EXPECT_EQ(child9(), iter.MoveToNext());
EXPECT_EQ(child9(), iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToNext());
EXPECT_EQ(nullptr, iter.GetCurrent());
EXPECT_EQ(nullptr, iter.MoveToNext());
EXPECT_EQ(nullptr, iter.GetCurrent());
}
TEST_F(XFANodeIteratorTest, SkipChildrenAndMoveToNext) {
Iterator iter(root());
iter.SetCurrent(child3());
EXPECT_EQ(child7(), iter.SkipChildrenAndMoveToNext());
EXPECT_EQ(child9(), iter.SkipChildrenAndMoveToNext());
EXPECT_EQ(nullptr, iter.SkipChildrenAndMoveToNext());
}
TEST_F(XFANodeIteratorTest, BackAndForth) {
Iterator iter(root());
EXPECT_EQ(child1(), iter.MoveToNext());
EXPECT_EQ(child2(), iter.MoveToNext());
EXPECT_EQ(child3(), iter.MoveToNext());
EXPECT_EQ(child4(), iter.MoveToNext());
EXPECT_EQ(child5(), iter.MoveToNext());
EXPECT_EQ(child4(), iter.MoveToPrev());
EXPECT_EQ(child3(), iter.MoveToPrev());
EXPECT_EQ(child2(), iter.MoveToPrev());
EXPECT_EQ(child1(), iter.MoveToPrev());
}
TEST_F(XFANodeIteratorTest, NextFromBeforeTheBeginning) {
Iterator iter(root());
EXPECT_EQ(nullptr, iter.MoveToPrev());
EXPECT_EQ(child1(), iter.MoveToNext());
}
TEST_F(XFANodeIteratorTest, PrevFromAfterTheEnd) {
Iterator iter(root());
iter.SetCurrent(child9());
EXPECT_EQ(nullptr, iter.MoveToNext());
EXPECT_EQ(child9(), iter.MoveToPrev());
}
TEST_F(XFANodeIteratorTest, ChildAsRootPrev) {
Iterator iter(child3());
EXPECT_EQ(nullptr, iter.MoveToPrev());
iter.SetCurrent(child4());
EXPECT_EQ(child3(), iter.MoveToPrev());
EXPECT_EQ(nullptr, iter.MoveToPrev());
}
TEST_F(XFANodeIteratorTest, ChildAsRootNext) {
Iterator iter(child3());
iter.SetCurrent(child4());
EXPECT_EQ(child5(), iter.MoveToNext());
EXPECT_EQ(child6(), iter.MoveToNext());
EXPECT_EQ(nullptr, iter.MoveToNext());
}