• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 "core/fxcrt/fx_string.h"
6 #include "core/fxcrt/xml/cfx_xmlelement.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 
9 namespace {
10 
ChildrenString(CFX_XMLElement * pParent)11 WideString ChildrenString(CFX_XMLElement* pParent) {
12   WideString result;
13   for (CFX_XMLNode* pChild = pParent->GetFirstChild(); pChild;
14        pChild = pChild->GetNextSibling()) {
15     result += static_cast<CFX_XMLElement*>(pChild)->GetName();
16   }
17   return result;
18 }
19 
ReverseChildrenString(CFX_XMLElement * pParent)20 WideString ReverseChildrenString(CFX_XMLElement* pParent) {
21   WideString result;
22   for (CFX_XMLNode* pChild = pParent->GetLastChild(); pChild;
23        pChild = pChild->GetPrevSibling()) {
24     result = static_cast<CFX_XMLElement*>(pChild)->GetName() + result;
25   }
26   return result;
27 }
28 
29 }  // namespace
30 
TEST(CFX_XMLNodeTest,GetParent)31 TEST(CFX_XMLNodeTest, GetParent) {
32   CFX_XMLElement node1(L"node");
33   CFX_XMLElement node2(L"node2");
34   CFX_XMLElement node3(L"node3");
35 
36   node1.AppendLastChild(&node2);
37   node2.AppendLastChild(&node3);
38 
39   EXPECT_EQ(nullptr, node1.GetParent());
40   EXPECT_EQ(&node1, node2.GetParent());
41   EXPECT_EQ(&node2, node3.GetParent());
42 }
43 
TEST(CFX_XMLNodeTest,GetRoot)44 TEST(CFX_XMLNodeTest, GetRoot) {
45   CFX_XMLElement node1(L"node");
46   CFX_XMLElement node2(L"node2");
47   CFX_XMLElement node3(L"node3");
48 
49   node1.AppendLastChild(&node2);
50   node2.AppendLastChild(&node3);
51 
52   EXPECT_EQ(&node1, node1.GetRoot());
53   EXPECT_EQ(&node1, node2.GetRoot());
54   EXPECT_EQ(&node1, node3.GetRoot());
55 }
56 
TEST(CFX_XMLNodeTest,GetChildren)57 TEST(CFX_XMLNodeTest, GetChildren) {
58   CFX_XMLElement node1(L"node");
59   CFX_XMLElement node2(L"node2");
60   CFX_XMLElement node3(L"node3");
61   CFX_XMLElement node4(L"node4");
62 
63   node1.AppendLastChild(&node2);
64   node1.AppendLastChild(&node4);
65   node2.AppendLastChild(&node3);
66 
67   EXPECT_EQ(&node2, node1.GetFirstChild());
68 
69   EXPECT_EQ(&node4, node2.GetNextSibling());
70   EXPECT_EQ(&node3, node2.GetFirstChild());
71 
72   EXPECT_TRUE(node3.GetNextSibling() == nullptr);
73   EXPECT_TRUE(node3.GetFirstChild() == nullptr);
74 
75   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
76   EXPECT_TRUE(node4.GetFirstChild() == nullptr);
77 }
78 
TEST(CFX_XMLNodeTest,DeleteChildren)79 TEST(CFX_XMLNodeTest, DeleteChildren) {
80   CFX_XMLElement node1(L"node");
81   CFX_XMLElement node2(L"node2");
82   CFX_XMLElement node3(L"node3");
83   CFX_XMLElement node4(L"node4");
84 
85   node1.AppendLastChild(&node2);
86   node1.AppendLastChild(&node4);
87   node2.AppendLastChild(&node3);
88 
89   node1.RemoveAllChildren();
90   EXPECT_TRUE(node1.GetFirstChild() == nullptr);
91   EXPECT_TRUE(node2.GetParent() == nullptr);
92   EXPECT_TRUE(node4.GetParent() == nullptr);
93 
94   // node2 and node4 should no longer be siblings.
95   EXPECT_TRUE(node2.GetNextSibling() == nullptr);
96   EXPECT_TRUE(node4.GetPrevSibling() == nullptr);
97 
98   // Deleting children doesn't change deleted substructure
99   EXPECT_EQ(&node3, node2.GetFirstChild());
100   EXPECT_TRUE(node3.GetParent() == &node2);
101 }
102 
TEST(CFX_XMLNodeTest,AddingChildren)103 TEST(CFX_XMLNodeTest, AddingChildren) {
104   CFX_XMLElement parent(L"Root");
105   CFX_XMLElement nodeA(L"A");
106   CFX_XMLElement nodeB(L"B");
107 
108   parent.AppendLastChild(&nodeA);
109   parent.AppendLastChild(&nodeB);
110 
111   EXPECT_EQ(L"AB", ChildrenString(&parent));
112   EXPECT_EQ(L"AB", ReverseChildrenString(&parent));
113   EXPECT_EQ(&parent, nodeA.GetParent());
114   EXPECT_EQ(&parent, nodeB.GetParent());
115   EXPECT_EQ(&nodeA, parent.GetFirstChild());
116   EXPECT_EQ(&nodeB, nodeA.GetNextSibling());
117   EXPECT_TRUE(nodeB.GetNextSibling() == nullptr);
118 
119   // Insert to negative appends last child.
120   CFX_XMLElement nodeC(L"C");
121   parent.InsertChildNode(&nodeC, -1);
122   EXPECT_EQ(L"ABC", ChildrenString(&parent));
123   EXPECT_EQ(L"ABC", ReverseChildrenString(&parent));
124   EXPECT_EQ(&parent, nodeC.GetParent());
125   EXPECT_EQ(&nodeC, nodeB.GetNextSibling());
126   EXPECT_TRUE(nodeC.GetNextSibling() == nullptr);
127 
128   // Insertion occurs before a zero based index.
129   CFX_XMLElement nodeD(L"D");
130   parent.InsertChildNode(&nodeD, 1);
131   EXPECT_EQ(L"ADBC", ChildrenString(&parent));
132   EXPECT_EQ(L"ADBC", ReverseChildrenString(&parent));
133 
134   // Insert to 0 appends first child.
135   CFX_XMLElement nodeE(L"E");
136   parent.InsertChildNode(&nodeE, 0);
137   EXPECT_EQ(L"EADBC", ChildrenString(&parent));
138   EXPECT_EQ(L"EADBC", ReverseChildrenString(&parent));
139 
140   // Insert to out-of-bounds index appends last child.
141   CFX_XMLElement nodeF(L"F");
142   parent.InsertChildNode(&nodeF, 10);
143   EXPECT_EQ(L"EADBCF", ChildrenString(&parent));
144   EXPECT_EQ(L"EADBCF", ReverseChildrenString(&parent));
145 }
146 
TEST(CFX_XMLNodeTest,RemovingMiddleChild)147 TEST(CFX_XMLNodeTest, RemovingMiddleChild) {
148   CFX_XMLElement node1(L"node1");
149   CFX_XMLElement node2(L"node2");
150   CFX_XMLElement node3(L"node3");
151   CFX_XMLElement node4(L"node4");
152 
153   node1.AppendLastChild(&node2);
154   node1.AppendLastChild(&node3);
155   node1.AppendLastChild(&node4);
156 
157   EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
158   EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
159   EXPECT_EQ(&node2, node1.GetFirstChild());
160   EXPECT_EQ(&node3, node2.GetNextSibling());
161   EXPECT_EQ(&node4, node3.GetNextSibling());
162   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
163 
164   node1.RemoveChild(&node3);
165 
166   EXPECT_EQ(L"node2node4", ChildrenString(&node1));
167   EXPECT_EQ(L"node2node4", ReverseChildrenString(&node1));
168   EXPECT_TRUE(node3.GetParent() == nullptr);
169   EXPECT_TRUE(node3.GetNextSibling() == nullptr);
170   EXPECT_TRUE(node3.GetPrevSibling() == nullptr);
171   EXPECT_EQ(&node2, node1.GetFirstChild());
172   EXPECT_EQ(&node4, node2.GetNextSibling());
173   EXPECT_EQ(&node2, node4.GetPrevSibling());
174   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
175 }
176 
TEST(CFX_XMLNodeTest,RemovingFirstChild)177 TEST(CFX_XMLNodeTest, RemovingFirstChild) {
178   CFX_XMLElement node1(L"node1");
179   CFX_XMLElement node2(L"node2");
180   CFX_XMLElement node3(L"node3");
181   CFX_XMLElement node4(L"node4");
182 
183   node1.AppendLastChild(&node2);
184   node1.AppendLastChild(&node3);
185   node1.AppendLastChild(&node4);
186 
187   EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
188   EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
189   EXPECT_EQ(&node2, node1.GetFirstChild());
190   EXPECT_EQ(&node3, node2.GetNextSibling());
191   EXPECT_EQ(&node4, node3.GetNextSibling());
192   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
193 
194   node1.RemoveChild(&node2);
195 
196   EXPECT_EQ(L"node3node4", ChildrenString(&node1));
197   EXPECT_EQ(L"node3node4", ReverseChildrenString(&node1));
198   EXPECT_TRUE(node2.GetParent() == nullptr);
199   EXPECT_TRUE(node2.GetNextSibling() == nullptr);
200   EXPECT_TRUE(node2.GetPrevSibling() == nullptr);
201   EXPECT_EQ(&node3, node1.GetFirstChild());
202   EXPECT_TRUE(node3.GetPrevSibling() == nullptr);
203   EXPECT_EQ(&node4, node3.GetNextSibling());
204   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
205 }
206 
TEST(CFX_XMLNodeTest,RemovingLastChild)207 TEST(CFX_XMLNodeTest, RemovingLastChild) {
208   CFX_XMLElement node1(L"node1");
209   CFX_XMLElement node2(L"node2");
210   CFX_XMLElement node3(L"node3");
211   CFX_XMLElement node4(L"node4");
212 
213   node1.AppendLastChild(&node2);
214   node1.AppendLastChild(&node3);
215   node1.AppendLastChild(&node4);
216 
217   EXPECT_EQ(L"node2node3node4", ChildrenString(&node1));
218   EXPECT_EQ(L"node2node3node4", ReverseChildrenString(&node1));
219   EXPECT_EQ(&node2, node1.GetFirstChild());
220   EXPECT_EQ(&node3, node2.GetNextSibling());
221   EXPECT_EQ(&node4, node3.GetNextSibling());
222   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
223 
224   node1.RemoveChild(&node4);
225 
226   EXPECT_EQ(L"node2node3", ChildrenString(&node1));
227   EXPECT_EQ(L"node2node3", ReverseChildrenString(&node1));
228   EXPECT_TRUE(node4.GetParent() == nullptr);
229   EXPECT_TRUE(node4.GetNextSibling() == nullptr);
230   EXPECT_TRUE(node4.GetPrevSibling() == nullptr);
231   EXPECT_EQ(&node2, node1.GetFirstChild());
232   EXPECT_EQ(&node3, node2.GetNextSibling());
233   EXPECT_TRUE(node3.GetNextSibling() == nullptr);
234 }
235 
TEST(CFX_XMLNodeTest,RemovingOnlyChild)236 TEST(CFX_XMLNodeTest, RemovingOnlyChild) {
237   CFX_XMLElement node1(L"node1");
238   CFX_XMLElement node2(L"node2");
239 
240   node1.AppendLastChild(&node2);
241 
242   EXPECT_EQ(&node2, node1.GetFirstChild());
243   EXPECT_TRUE(node2.GetNextSibling() == nullptr);
244 
245   node1.RemoveChild(&node2);
246   EXPECT_TRUE(node2.GetParent() == nullptr);
247 
248   EXPECT_TRUE(node1.GetFirstChild() == nullptr);
249   EXPECT_TRUE(node2.GetNextSibling() == nullptr);
250   EXPECT_TRUE(node2.GetPrevSibling() == nullptr);
251 }
252 
TEST(CFX_XMLNodeTest,RemoveMissingChild)253 TEST(CFX_XMLNodeTest, RemoveMissingChild) {
254   CFX_XMLElement node1(L"node1");
255   CFX_XMLElement node2(L"node2");
256   CFX_XMLElement node3(L"node3");
257 
258   node1.AppendLastChild(&node2);
259   EXPECT_DEATH(node1.RemoveChild(&node3), "");
260 }
261