1 // Copyright 2019 The PDFium Authors
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 "core/fxcrt/tree_node.h"
6
7 #include <memory>
8
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace fxcrt {
12
13 class TestTreeNode : public TreeNode<TestTreeNode> {};
14
15 // NOTE: Successful cases are covered via RetainedTreeNode tests.
16 // These tests check that we trip CHECKS given bad calls.
17
TEST(TreeNode,SelfAppendFirstChild)18 TEST(TreeNode, SelfAppendFirstChild) {
19 auto pNode = std::make_unique<TestTreeNode>();
20 EXPECT_DEATH(pNode->AppendFirstChild(pNode.get()), "");
21 }
22
TEST(TreeNode,SelfAppendLastChild)23 TEST(TreeNode, SelfAppendLastChild) {
24 auto pNode = std::make_unique<TestTreeNode>();
25 EXPECT_DEATH(pNode->AppendLastChild(pNode.get()), "");
26 }
27
TEST(TreeNode,SelfInsertBeforeOther)28 TEST(TreeNode, SelfInsertBeforeOther) {
29 auto pNode = std::make_unique<TestTreeNode>();
30 auto pOther = std::make_unique<TestTreeNode>();
31 pNode->AppendFirstChild(pOther.get());
32 EXPECT_DEATH(pNode->InsertBefore(pNode.get(), pOther.get()), "");
33 }
34
TEST(TreeNode,InsertOtherBeforeSelf)35 TEST(TreeNode, InsertOtherBeforeSelf) {
36 auto pNode = std::make_unique<TestTreeNode>();
37 auto pOther = std::make_unique<TestTreeNode>();
38 pNode->AppendFirstChild(pOther.get());
39 EXPECT_DEATH(pNode->InsertBefore(pOther.get(), pNode.get()), "");
40 }
41
TEST(TreeNode,SelfInsertAfterOther)42 TEST(TreeNode, SelfInsertAfterOther) {
43 auto pNode = std::make_unique<TestTreeNode>();
44 auto pOther = std::make_unique<TestTreeNode>();
45 pNode->AppendFirstChild(pOther.get());
46 EXPECT_DEATH(pNode->InsertBefore(pNode.get(), pOther.get()), "");
47 }
48
TEST(TreeNode,InsertOtherAfterSelf)49 TEST(TreeNode, InsertOtherAfterSelf) {
50 auto pNode = std::make_unique<TestTreeNode>();
51 auto pOther = std::make_unique<TestTreeNode>();
52 pNode->AppendFirstChild(pOther.get());
53 EXPECT_DEATH(pNode->InsertBefore(pOther.get(), pNode.get()), "");
54 }
55
TEST(TreeNode,RemoveParentless)56 TEST(TreeNode, RemoveParentless) {
57 auto pNode = std::make_unique<TestTreeNode>();
58 EXPECT_DEATH(pNode->GetParent()->RemoveChild(pNode.get()), "");
59 }
60
TEST(TreeNode,RemoveFromWrongParent)61 TEST(TreeNode, RemoveFromWrongParent) {
62 auto pGoodParent = std::make_unique<TestTreeNode>();
63 auto pBadParent = std::make_unique<TestTreeNode>();
64 auto pNode = std::make_unique<TestTreeNode>();
65 pGoodParent->AppendFirstChild(pNode.get());
66 EXPECT_DEATH(pBadParent->RemoveChild(pNode.get()), "");
67 }
68
TEST(TreeNode,SafeRemove)69 TEST(TreeNode, SafeRemove) {
70 auto pParent = std::make_unique<TestTreeNode>();
71 auto pChild = std::make_unique<TestTreeNode>();
72 pParent->AppendFirstChild(pChild.get());
73 pChild->RemoveSelfIfParented();
74 EXPECT_FALSE(pParent->GetFirstChild());
75 EXPECT_FALSE(pChild->GetParent());
76 }
77
TEST(TreeNode,SafeRemoveParentless)78 TEST(TreeNode, SafeRemoveParentless) {
79 auto pNode = std::make_unique<TestTreeNode>();
80 pNode->RemoveSelfIfParented();
81 EXPECT_FALSE(pNode->GetParent());
82 }
83
TEST(TreeNode,RemoveAllChildren)84 TEST(TreeNode, RemoveAllChildren) {
85 auto pParent = std::make_unique<TestTreeNode>();
86 pParent->RemoveAllChildren();
87 EXPECT_FALSE(pParent->GetFirstChild());
88
89 auto p0 = std::make_unique<TestTreeNode>();
90 auto p1 = std::make_unique<TestTreeNode>();
91 auto p2 = std::make_unique<TestTreeNode>();
92 auto p3 = std::make_unique<TestTreeNode>();
93 pParent->AppendLastChild(p0.get());
94 pParent->AppendLastChild(p1.get());
95 pParent->AppendLastChild(p2.get());
96 pParent->AppendLastChild(p3.get());
97 pParent->RemoveAllChildren();
98 EXPECT_FALSE(pParent->GetFirstChild());
99 }
100
TEST(TreeNode,NthChild)101 TEST(TreeNode, NthChild) {
102 auto pParent = std::make_unique<TestTreeNode>();
103 EXPECT_FALSE(pParent->GetNthChild(-1));
104 EXPECT_FALSE(pParent->GetNthChild(0));
105
106 auto p0 = std::make_unique<TestTreeNode>();
107 auto p1 = std::make_unique<TestTreeNode>();
108 auto p2 = std::make_unique<TestTreeNode>();
109 auto p3 = std::make_unique<TestTreeNode>();
110 pParent->AppendLastChild(p0.get());
111 pParent->AppendLastChild(p1.get());
112 pParent->AppendLastChild(p2.get());
113 pParent->AppendLastChild(p3.get());
114 EXPECT_FALSE(pParent->GetNthChild(-1));
115 EXPECT_EQ(p0.get(), pParent->GetNthChild(0));
116 EXPECT_EQ(p1.get(), pParent->GetNthChild(1));
117 EXPECT_EQ(p2.get(), pParent->GetNthChild(2));
118 EXPECT_EQ(p3.get(), pParent->GetNthChild(3));
119 EXPECT_FALSE(pParent->GetNthChild(4));
120 pParent->RemoveAllChildren();
121 }
122
TEST(TreeNode,AppendFirstChild)123 TEST(TreeNode, AppendFirstChild) {
124 auto parent = std::make_unique<TestTreeNode>();
125 auto child0 = std::make_unique<TestTreeNode>();
126 auto child1 = std::make_unique<TestTreeNode>();
127 parent->AppendFirstChild(child0.get());
128 EXPECT_EQ(child0.get(), parent->GetFirstChild());
129 parent->AppendFirstChild(child1.get());
130 EXPECT_EQ(child1.get(), parent->GetFirstChild());
131 EXPECT_EQ(child1.get(), parent->GetNthChild(0));
132 EXPECT_EQ(child0.get(), parent->GetNthChild(1));
133 }
134
TEST(TreeNode,RemoveChild)135 TEST(TreeNode, RemoveChild) {
136 auto parent = std::make_unique<TestTreeNode>();
137 auto child0 = std::make_unique<TestTreeNode>();
138 auto child1 = std::make_unique<TestTreeNode>();
139
140 parent->AppendFirstChild(child0.get());
141 parent->AppendLastChild(child1.get());
142 EXPECT_EQ(child0.get(), parent->GetFirstChild());
143 EXPECT_EQ(child1.get(), parent->GetLastChild());
144 parent->RemoveChild(child0.get());
145 EXPECT_EQ(child1.get(), parent->GetFirstChild());
146 EXPECT_EQ(child1.get(), parent->GetLastChild());
147 parent->RemoveChild(child1.get());
148 EXPECT_FALSE(parent->GetFirstChild());
149 EXPECT_FALSE(parent->GetLastChild());
150
151 parent->AppendFirstChild(child0.get());
152 parent->AppendLastChild(child1.get());
153 EXPECT_EQ(child0.get(), parent->GetFirstChild());
154 EXPECT_EQ(child1.get(), parent->GetLastChild());
155 parent->RemoveChild(child1.get());
156 EXPECT_EQ(child0.get(), parent->GetFirstChild());
157 EXPECT_EQ(child0.get(), parent->GetLastChild());
158 parent->RemoveChild(child0.get());
159 EXPECT_FALSE(parent->GetFirstChild());
160 EXPECT_FALSE(parent->GetLastChild());
161 }
162
163 } // namespace fxcrt
164