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_node.h"
6
7 #include "fxjs/xfa/cjx_node.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/base/ptr_util.h"
10 #include "xfa/fxfa/parser/cxfa_document.h"
11
12 namespace {
13
14 class TestNode final : public CXFA_Node {
15 public:
TestNode(CXFA_Document * doc)16 explicit TestNode(CXFA_Document* doc)
17 : CXFA_Node(doc,
18 XFA_PacketType::Form,
19 (XFA_XDPPACKET_Template | XFA_XDPPACKET_Form),
20 XFA_ObjectType::Node,
21 XFA_Element::Node,
22 {},
23 {},
24 pdfium::MakeUnique<CJX_Node>(this)) {}
25
26 ~TestNode() override = default;
27 };
28
29 } // namespace
30
31 class CXFANodeTest : public testing::Test {
32 public:
SetUp()33 void SetUp() override {
34 doc_ = pdfium::MakeUnique<CXFA_Document>(nullptr, nullptr);
35 node_ = pdfium::MakeUnique<TestNode>(doc_.get());
36 }
37
TearDown()38 void TearDown() override {
39 node_ = nullptr;
40 doc_ = nullptr;
41 }
42
GetDoc() const43 CXFA_Document* GetDoc() const { return doc_.get(); }
GetNode() const44 CXFA_Node* GetNode() const { return node_.get(); }
45
46 private:
47 std::unique_ptr<CXFA_Document> doc_;
48 std::unique_ptr<TestNode> node_;
49 };
50
TEST_F(CXFANodeTest,InsertFirstChild)51 TEST_F(CXFANodeTest, InsertFirstChild) {
52 EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
53 EXPECT_EQ(nullptr, GetNode()->GetLastChild());
54
55 CXFA_Node* child =
56 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
57 GetNode()->InsertChildAndNotify(-1, child);
58
59 EXPECT_EQ(GetNode(), child->GetParent());
60 EXPECT_EQ(child, GetNode()->GetFirstChild());
61 EXPECT_EQ(child, GetNode()->GetLastChild());
62 EXPECT_EQ(nullptr, child->GetPrevSibling());
63 EXPECT_EQ(nullptr, child->GetNextSibling());
64 }
65
TEST_F(CXFANodeTest,InsertChildByNegativeIndex)66 TEST_F(CXFANodeTest, InsertChildByNegativeIndex) {
67 CXFA_Node* child0 =
68 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
69 GetNode()->InsertChildAndNotify(-1, child0);
70
71 CXFA_Node* child =
72 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
73 GetNode()->InsertChildAndNotify(-1, child);
74
75 EXPECT_EQ(GetNode(), child->GetParent());
76 EXPECT_EQ(nullptr, child->GetNextSibling());
77 EXPECT_EQ(child0, child->GetPrevSibling());
78 EXPECT_EQ(child, child0->GetNextSibling());
79 EXPECT_EQ(nullptr, child0->GetPrevSibling());
80
81 EXPECT_EQ(child0, GetNode()->GetFirstChild());
82 EXPECT_EQ(child, GetNode()->GetLastChild());
83 }
84
TEST_F(CXFANodeTest,InsertChildByIndex)85 TEST_F(CXFANodeTest, InsertChildByIndex) {
86 CXFA_Node* child0 =
87 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
88 GetNode()->InsertChildAndNotify(-1, child0);
89
90 CXFA_Node* child1 =
91 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
92 GetNode()->InsertChildAndNotify(-1, child1);
93
94 CXFA_Node* child2 =
95 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
96 GetNode()->InsertChildAndNotify(-1, child2);
97
98 CXFA_Node* child3 =
99 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
100 GetNode()->InsertChildAndNotify(-1, child3);
101
102 CXFA_Node* child =
103 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
104 GetNode()->InsertChildAndNotify(2, child);
105
106 EXPECT_EQ(GetNode(), child->GetParent());
107
108 EXPECT_EQ(child0, GetNode()->GetFirstChild());
109 EXPECT_EQ(child1, child0->GetNextSibling());
110 EXPECT_EQ(child, child1->GetNextSibling());
111 EXPECT_EQ(child2, child->GetNextSibling());
112 EXPECT_EQ(child3, child2->GetNextSibling());
113 EXPECT_EQ(nullptr, child3->GetNextSibling());
114
115 EXPECT_EQ(child3, GetNode()->GetLastChild());
116 EXPECT_EQ(child2, child3->GetPrevSibling());
117 EXPECT_EQ(child, child2->GetPrevSibling());
118 EXPECT_EQ(child1, child->GetPrevSibling());
119 EXPECT_EQ(child0, child1->GetPrevSibling());
120 EXPECT_EQ(nullptr, child0->GetPrevSibling());
121 }
122
TEST_F(CXFANodeTest,InsertChildIndexPastEnd)123 TEST_F(CXFANodeTest, InsertChildIndexPastEnd) {
124 CXFA_Node* child0 =
125 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
126 GetNode()->InsertChildAndNotify(-1, child0);
127
128 CXFA_Node* child1 =
129 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
130 GetNode()->InsertChildAndNotify(-1, child1);
131
132 CXFA_Node* child =
133 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
134 GetNode()->InsertChildAndNotify(20, child);
135
136 EXPECT_EQ(GetNode(), child->GetParent());
137 EXPECT_EQ(nullptr, child->GetNextSibling());
138 EXPECT_EQ(child1, child->GetPrevSibling());
139 EXPECT_EQ(child, child1->GetNextSibling());
140
141 EXPECT_EQ(child0, GetNode()->GetFirstChild());
142 EXPECT_EQ(child, GetNode()->GetLastChild());
143 }
144
TEST_F(CXFANodeTest,InsertFirstChildBeforeNullptr)145 TEST_F(CXFANodeTest, InsertFirstChildBeforeNullptr) {
146 EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
147 EXPECT_EQ(nullptr, GetNode()->GetLastChild());
148
149 CXFA_Node* child =
150 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
151 GetNode()->InsertChildAndNotify(child, nullptr);
152 EXPECT_EQ(child, GetNode()->GetFirstChild());
153 EXPECT_EQ(child, GetNode()->GetLastChild());
154 }
155
TEST_F(CXFANodeTest,InsertBeforeWithNullBefore)156 TEST_F(CXFANodeTest, InsertBeforeWithNullBefore) {
157 CXFA_Node* child0 =
158 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
159 GetNode()->InsertChildAndNotify(-1, child0);
160
161 CXFA_Node* child1 =
162 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
163 GetNode()->InsertChildAndNotify(-1, child1);
164
165 CXFA_Node* child =
166 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
167 GetNode()->InsertChildAndNotify(child, nullptr);
168
169 EXPECT_EQ(GetNode(), child->GetParent());
170 EXPECT_EQ(nullptr, child->GetNextSibling());
171 EXPECT_EQ(child1, child->GetPrevSibling());
172 EXPECT_EQ(child, child1->GetNextSibling());
173
174 EXPECT_EQ(child0, GetNode()->GetFirstChild());
175 EXPECT_EQ(child, GetNode()->GetLastChild());
176 }
177
TEST_F(CXFANodeTest,InsertBeforeFirstChild)178 TEST_F(CXFANodeTest, InsertBeforeFirstChild) {
179 CXFA_Node* child0 =
180 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
181 GetNode()->InsertChildAndNotify(-1, child0);
182
183 CXFA_Node* child1 =
184 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
185 GetNode()->InsertChildAndNotify(-1, child1);
186
187 CXFA_Node* child =
188 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
189 GetNode()->InsertChildAndNotify(child, child0);
190
191 EXPECT_EQ(GetNode(), child->GetParent());
192 EXPECT_EQ(child0, child->GetNextSibling());
193 EXPECT_EQ(nullptr, child->GetPrevSibling());
194 EXPECT_EQ(child, child0->GetPrevSibling());
195
196 EXPECT_EQ(child, GetNode()->GetFirstChild());
197 EXPECT_EQ(child1, GetNode()->GetLastChild());
198 }
199
TEST_F(CXFANodeTest,InsertBefore)200 TEST_F(CXFANodeTest, InsertBefore) {
201 CXFA_Node* child0 =
202 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
203 GetNode()->InsertChildAndNotify(-1, child0);
204
205 CXFA_Node* child1 =
206 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
207 GetNode()->InsertChildAndNotify(-1, child1);
208
209 CXFA_Node* child2 =
210 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
211 GetNode()->InsertChildAndNotify(-1, child2);
212
213 CXFA_Node* child3 =
214 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
215 GetNode()->InsertChildAndNotify(-1, child3);
216
217 CXFA_Node* child =
218 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
219 GetNode()->InsertChildAndNotify(child, child2);
220
221 EXPECT_EQ(GetNode(), child->GetParent());
222 EXPECT_EQ(child2, child->GetNextSibling());
223 EXPECT_EQ(child1, child->GetPrevSibling());
224 EXPECT_EQ(child, child1->GetNextSibling());
225 EXPECT_EQ(child, child2->GetPrevSibling());
226
227 EXPECT_EQ(child0, GetNode()->GetFirstChild());
228 EXPECT_EQ(child3, GetNode()->GetLastChild());
229 }
230
TEST_F(CXFANodeTest,RemoveOnlyChild)231 TEST_F(CXFANodeTest, RemoveOnlyChild) {
232 CXFA_Node* child0 =
233 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
234 GetNode()->InsertChildAndNotify(-1, child0);
235 EXPECT_EQ(child0, GetNode()->GetFirstChild());
236 EXPECT_EQ(child0, GetNode()->GetLastChild());
237
238 GetNode()->RemoveChildAndNotify(child0, false);
239 EXPECT_EQ(nullptr, GetNode()->GetFirstChild());
240 EXPECT_EQ(nullptr, GetNode()->GetLastChild());
241 EXPECT_EQ(nullptr, child0->GetParent());
242 EXPECT_EQ(nullptr, child0->GetNextSibling());
243 EXPECT_EQ(nullptr, child0->GetPrevSibling());
244 }
245
TEST_F(CXFANodeTest,RemoveFirstChild)246 TEST_F(CXFANodeTest, RemoveFirstChild) {
247 CXFA_Node* child0 =
248 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
249 GetNode()->InsertChildAndNotify(-1, child0);
250
251 CXFA_Node* child1 =
252 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
253 GetNode()->InsertChildAndNotify(-1, child1);
254
255 CXFA_Node* child2 =
256 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
257 GetNode()->InsertChildAndNotify(-1, child2);
258 EXPECT_EQ(child0, GetNode()->GetFirstChild());
259 EXPECT_EQ(child2, GetNode()->GetLastChild());
260
261 GetNode()->RemoveChildAndNotify(child0, false);
262 EXPECT_EQ(child1, GetNode()->GetFirstChild());
263 EXPECT_EQ(child2, GetNode()->GetLastChild());
264 EXPECT_EQ(nullptr, child1->GetPrevSibling());
265 EXPECT_EQ(nullptr, child0->GetParent());
266 EXPECT_EQ(nullptr, child0->GetNextSibling());
267 EXPECT_EQ(nullptr, child0->GetPrevSibling());
268 }
269
TEST_F(CXFANodeTest,RemoveLastChild)270 TEST_F(CXFANodeTest, RemoveLastChild) {
271 CXFA_Node* child0 =
272 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
273 GetNode()->InsertChildAndNotify(-1, child0);
274
275 CXFA_Node* child1 =
276 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
277 GetNode()->InsertChildAndNotify(-1, child1);
278
279 CXFA_Node* child2 =
280 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
281 GetNode()->InsertChildAndNotify(-1, child2);
282 EXPECT_EQ(child0, GetNode()->GetFirstChild());
283 EXPECT_EQ(child2, GetNode()->GetLastChild());
284
285 GetNode()->RemoveChildAndNotify(child2, false);
286 EXPECT_EQ(child0, GetNode()->GetFirstChild());
287 EXPECT_EQ(child1, GetNode()->GetLastChild());
288 EXPECT_EQ(nullptr, child1->GetNextSibling());
289 EXPECT_EQ(nullptr, child2->GetParent());
290 EXPECT_EQ(nullptr, child2->GetNextSibling());
291 EXPECT_EQ(nullptr, child2->GetPrevSibling());
292 }
293
TEST_F(CXFANodeTest,RemoveChild)294 TEST_F(CXFANodeTest, RemoveChild) {
295 CXFA_Node* child0 =
296 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
297 GetNode()->InsertChildAndNotify(-1, child0);
298
299 CXFA_Node* child1 =
300 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
301 GetNode()->InsertChildAndNotify(-1, child1);
302
303 CXFA_Node* child2 =
304 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
305 GetNode()->InsertChildAndNotify(-1, child2);
306 EXPECT_EQ(child0, GetNode()->GetFirstChild());
307 EXPECT_EQ(child2, GetNode()->GetLastChild());
308
309 GetNode()->RemoveChildAndNotify(child1, false);
310 EXPECT_EQ(child0, GetNode()->GetFirstChild());
311 EXPECT_EQ(child2, GetNode()->GetLastChild());
312 EXPECT_EQ(child2, child0->GetNextSibling());
313 EXPECT_EQ(child0, child2->GetPrevSibling());
314 EXPECT_EQ(nullptr, child1->GetParent());
315 EXPECT_EQ(nullptr, child1->GetNextSibling());
316 EXPECT_EQ(nullptr, child1->GetPrevSibling());
317 }
318
TEST_F(CXFANodeTest,InsertChildWithParent)319 TEST_F(CXFANodeTest, InsertChildWithParent) {
320 CXFA_Node* child0 =
321 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
322 CXFA_Node* child1 =
323 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
324 child0->InsertChildAndNotify(-1, child1);
325
326 EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, child1), "");
327 }
328
TEST_F(CXFANodeTest,InsertNullChild)329 TEST_F(CXFANodeTest, InsertNullChild) {
330 EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(0, nullptr), "");
331 }
332
TEST_F(CXFANodeTest,InsertBeforeWithNullChild)333 TEST_F(CXFANodeTest, InsertBeforeWithNullChild) {
334 EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(nullptr, nullptr),
335 "");
336 }
337
TEST_F(CXFANodeTest,InsertBeforeWithBeforeInAnotherParent)338 TEST_F(CXFANodeTest, InsertBeforeWithBeforeInAnotherParent) {
339 CXFA_Node* child0 =
340 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
341 GetNode()->InsertChildAndNotify(-1, child0);
342
343 CXFA_Node* child1 =
344 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
345 child0->InsertChildAndNotify(-1, child1);
346
347 CXFA_Node* child =
348 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
349 EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child, child1), "");
350 }
351
TEST_F(CXFANodeTest,InsertBeforeWithNodeInAnotherParent)352 TEST_F(CXFANodeTest, InsertBeforeWithNodeInAnotherParent) {
353 CXFA_Node* child0 =
354 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
355 GetNode()->InsertChildAndNotify(-1, child0);
356
357 CXFA_Node* child1 =
358 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
359 child0->InsertChildAndNotify(-1, child1);
360
361 EXPECT_DEATH_IF_SUPPORTED(GetNode()->InsertChildAndNotify(child1, nullptr),
362 "");
363 }
364
TEST_F(CXFANodeTest,RemoveChildNullptr)365 TEST_F(CXFANodeTest, RemoveChildNullptr) {
366 EXPECT_DEATH_IF_SUPPORTED(GetNode()->RemoveChildAndNotify(nullptr, false),
367 "");
368 }
369
TEST_F(CXFANodeTest,RemoveChildAnotherParent)370 TEST_F(CXFANodeTest, RemoveChildAnotherParent) {
371 CXFA_Node* child0 =
372 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
373 GetNode()->InsertChildAndNotify(-1, child0);
374
375 CXFA_Node* child1 =
376 GetDoc()->CreateNode(XFA_PacketType::Form, XFA_Element::Ui);
377 child0->InsertChildAndNotify(-1, child1);
378
379 GetNode()->RemoveChildAndNotify(child1, false);
380 EXPECT_EQ(child0, child1->GetParent());
381 }
382