• 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/xml/cfx_xmlelement.h"
6 #include "core/fxcrt/xml/cfx_xmlchardata.h"
7 #include "core/fxcrt/xml/cfx_xmldocument.h"
8 #include "core/fxcrt/xml/cfx_xmltext.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/string_write_stream.h"
11 
TEST(CFX_XMLElementTest,GetType)12 TEST(CFX_XMLElementTest, GetType) {
13   CFX_XMLElement node(L"node");
14   EXPECT_EQ(CFX_XMLNode::Type::kElement, node.GetType());
15 }
16 
TEST(CFX_XMLElementTest,GetName)17 TEST(CFX_XMLElementTest, GetName) {
18   CFX_XMLElement node(L"node");
19   EXPECT_EQ(L"node", node.GetName());
20 }
21 
TEST(CFX_XMLElementTest,GetLocalTagName)22 TEST(CFX_XMLElementTest, GetLocalTagName) {
23   CFX_XMLElement node1(L"node1");
24   EXPECT_EQ(L"node1", node1.GetLocalTagName());
25 
26   CFX_XMLElement node2(L"test:node2");
27   EXPECT_EQ(L"node2", node2.GetLocalTagName());
28 }
29 
TEST(CFX_XMLElementTest,GetNamespacePrefix)30 TEST(CFX_XMLElementTest, GetNamespacePrefix) {
31   CFX_XMLElement node1(L"node1");
32   EXPECT_EQ(L"", node1.GetNamespacePrefix());
33 
34   CFX_XMLElement node2(L"test:node2");
35   EXPECT_EQ(L"test", node2.GetNamespacePrefix());
36 }
37 
TEST(CFX_XMLElementTest,GetNamespaceURI)38 TEST(CFX_XMLElementTest, GetNamespaceURI) {
39   CFX_XMLElement node1(L"node1");
40   EXPECT_EQ(L"", node1.GetNamespaceURI());
41 
42   node1.SetAttribute(L"xmlns", L"https://example.org/ns1");
43   EXPECT_EQ(L"https://example.org/ns1", node1.GetNamespaceURI());
44 
45   CFX_XMLElement node2(L"test:node2");
46   EXPECT_EQ(L"", node2.GetNamespaceURI());
47 
48   node2.SetAttribute(L"xmlns", L"https://example.org/ns2");
49   EXPECT_EQ(L"", node2.GetNamespaceURI());
50 
51   node2.SetAttribute(L"xmlns:test", L"https://example.org/ns2");
52   EXPECT_EQ(L"https://example.org/ns2", node2.GetNamespaceURI());
53 }
54 
TEST(CFX_XMLElementTest,Attributes)55 TEST(CFX_XMLElementTest, Attributes) {
56   CFX_XMLElement node(L"test:node");
57   node.SetAttribute(L"first", L"one");
58   node.SetAttribute(L"second", L"two");
59 
60   ASSERT_TRUE(node.HasAttribute(L"first"));
61   EXPECT_EQ(L"one", node.GetAttribute(L"first"));
62   ASSERT_TRUE(node.HasAttribute(L"second"));
63   EXPECT_EQ(L"two", node.GetAttribute(L"second"));
64 
65   ASSERT_EQ(2U, node.GetAttributes().size());
66 
67   node.RemoveAttribute(L"first");
68   EXPECT_FALSE(node.HasAttribute(L"first"));
69 
70   ASSERT_EQ(1U, node.GetAttributes().size());
71 }
72 
TEST(CFX_XMLElementTest,Clone)73 TEST(CFX_XMLElementTest, Clone) {
74   CFX_XMLDocument doc;
75   CFX_XMLElement node(L"test:node");
76   node.SetAttribute(L"first", L"one");
77   node.SetAttribute(L"second", L"two");
78   node.SetAttribute(L"xmlns:test", L"https://example.org/test");
79 
80   CFX_XMLText text_child1(L"Text Child");
81   node.AppendLastChild(&text_child1);
82 
83   CFX_XMLElement node_child1(L"Node child");
84   node.AppendLastChild(&node_child1);
85 
86   CFX_XMLNode* clone = node.Clone(&doc);
87   EXPECT_TRUE(clone != nullptr);
88   ASSERT_EQ(CFX_XMLNode::Type::kElement, clone->GetType());
89 
90   CFX_XMLElement* inst = ToXMLElement(clone);
91   EXPECT_EQ(L"test:node", inst->GetName());
92   EXPECT_EQ(L"node", inst->GetLocalTagName());
93   EXPECT_EQ(L"test", inst->GetNamespacePrefix());
94   EXPECT_EQ(L"https://example.org/test", inst->GetNamespaceURI());
95 
96   ASSERT_TRUE(inst->HasAttribute(L"first"));
97   EXPECT_EQ(L"one", inst->GetAttribute(L"first"));
98   ASSERT_TRUE(inst->HasAttribute(L"second"));
99   EXPECT_EQ(L"two", inst->GetAttribute(L"second"));
100 
101   // Only clone the Text node, so expect only one child.
102   ASSERT_TRUE(inst->GetFirstChild() != nullptr);
103   EXPECT_TRUE(inst->GetFirstChild()->GetNextSibling() == nullptr);
104 
105   ASSERT_EQ(CFX_XMLNode::Type::kText, inst->GetFirstChild()->GetType());
106   auto* text = ToXMLText(inst->GetFirstChild());
107   EXPECT_EQ(L"Text Child", text->GetText());
108 }
109 
TEST(CFX_XMLElementTest,Save)110 TEST(CFX_XMLElementTest, Save) {
111   auto stream = pdfium::MakeRetain<StringWriteStream>();
112   CFX_XMLElement node(L"root");
113 
114   node.Save(stream);
115   EXPECT_EQ("<root />\n", stream->ToString());
116 }
117 
TEST(CFX_XMLElementTest,SaveWithAttributes)118 TEST(CFX_XMLElementTest, SaveWithAttributes) {
119   auto stream = pdfium::MakeRetain<StringWriteStream>();
120   CFX_XMLElement node(L"root");
121   node.SetAttribute(L"first", L"one");
122   node.SetAttribute(L"second", L"two");
123 
124   node.Save(stream);
125   EXPECT_EQ("<root first=\"one\" second=\"two\" />\n", stream->ToString());
126 }
127 
TEST(CFX_XMLElementTest,SaveWithChildren)128 TEST(CFX_XMLElementTest, SaveWithChildren) {
129   auto stream = pdfium::MakeRetain<StringWriteStream>();
130   CFX_XMLElement node(L"node");
131 
132   CFX_XMLText text_child1(L"Text Child 1");
133   node.AppendLastChild(&text_child1);
134 
135   CFX_XMLElement node_child1(L"node-child");
136   node.AppendLastChild(&node_child1);
137 
138   CFX_XMLText text_child2(L"Text Child 2");
139   node_child1.AppendLastChild(&text_child2);
140 
141   CFX_XMLCharData char_data1(L"Char Data");
142   node.AppendLastChild(&char_data1);
143 
144   node.Save(stream);
145   EXPECT_EQ(
146       "<node>\n"
147       "Text Child 1"
148       "<node-child>\nText Child 2</node-child>\n"
149       "<![CDATA[Char Data]]>"
150       "</node>\n",
151       stream->ToString());
152 }
153 
TEST(CFX_XMLElementTest,SaveWithNamespace)154 TEST(CFX_XMLElementTest, SaveWithNamespace) {
155   auto stream = pdfium::MakeRetain<StringWriteStream>();
156   CFX_XMLElement node(L"test:root");
157   node.SetAttribute(L"xmlns:test", L"https://example.org/ns1");
158 
159   node.Save(stream);
160   EXPECT_EQ("<test:root xmlns:test=\"https://example.org/ns1\" />\n",
161             stream->ToString());
162 }
163 
TEST(CFX_XMLElementTest,GetFirstChildNamed)164 TEST(CFX_XMLElementTest, GetFirstChildNamed) {
165   CFX_XMLElement node(L"node");
166   CFX_XMLElement node_child1(L"node-child");
167   node.AppendLastChild(&node_child1);
168 
169   auto* found = node.GetFirstChildNamed(L"node-child");
170   EXPECT_TRUE(found != nullptr);
171   EXPECT_EQ(&node_child1, found);
172 }
173 
TEST(CFX_XMLElementTest,GetFirstChildNamedMissing)174 TEST(CFX_XMLElementTest, GetFirstChildNamedMissing) {
175   CFX_XMLElement node(L"node");
176   CFX_XMLElement node_child1(L"node-child");
177   node.AppendLastChild(&node_child1);
178 
179   auto* found = node.GetFirstChildNamed(L"node-sibling");
180   EXPECT_TRUE(found == nullptr);
181 }
182 
TEST(CFX_XMLElementTest,GetNthChildNamed)183 TEST(CFX_XMLElementTest, GetNthChildNamed) {
184   CFX_XMLElement node(L"node");
185   CFX_XMLElement node_child1(L"node-child");
186   CFX_XMLElement node_child2(L"node-child");
187   CFX_XMLElement node_child3(L"node-child");
188   node.AppendLastChild(&node_child1);
189   node.AppendLastChild(&node_child2);
190   node.AppendLastChild(&node_child3);
191 
192   auto* found = node.GetNthChildNamed(L"node-child", 2);
193   EXPECT_TRUE(found != nullptr);
194   EXPECT_EQ(&node_child3, found);
195 }
196 
TEST(CFX_XMLElementTest,GetNthChildNamedMissingChild)197 TEST(CFX_XMLElementTest, GetNthChildNamedMissingChild) {
198   CFX_XMLElement node(L"node");
199   CFX_XMLElement node_child1(L"node-child");
200   CFX_XMLElement node_child2(L"node-child");
201   CFX_XMLElement node_child3(L"node-child");
202   node.AppendLastChild(&node_child1);
203   node.AppendLastChild(&node_child2);
204   node.AppendLastChild(&node_child3);
205 
206   auto* found = node.GetNthChildNamed(L"node-child", 5);
207   EXPECT_TRUE(found == nullptr);
208 }
209 
TEST(CFX_XMLElementTest,GetTextData)210 TEST(CFX_XMLElementTest, GetTextData) {
211   CFX_XMLElement node(L"node");
212 
213   CFX_XMLText text_child1(L"Text Child 1");
214   node.AppendLastChild(&text_child1);
215 
216   CFX_XMLElement node_child1(L"Node child");
217   node.AppendLastChild(&node_child1);
218 
219   CFX_XMLText text_child2(L"Text Child 2");
220   node_child1.AppendLastChild(&text_child2);
221 
222   CFX_XMLCharData char_data1(L"Char Data");
223   node.AppendLastChild(&char_data1);
224 
225   EXPECT_EQ(L"Text Child 1Char Data", node.GetTextData());
226 }
227