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_xmlinstruction.h"
6
7 #include <memory>
8
9 #include "core/fxcrt/cfx_readonlymemorystream.h"
10 #include "core/fxcrt/xml/cfx_xmldocument.h"
11 #include "core/fxcrt/xml/cfx_xmlelement.h"
12 #include "core/fxcrt/xml/cfx_xmlparser.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "testing/string_write_stream.h"
15
TEST(CFX_XMLInstructionTest,GetType)16 TEST(CFX_XMLInstructionTest, GetType) {
17 CFX_XMLInstruction node(L"acrobat");
18 EXPECT_EQ(CFX_XMLNode::Type::kInstruction, node.GetType());
19 }
20
TEST(CFX_XMLInstructionTest,AcrobatInstruction)21 TEST(CFX_XMLInstructionTest, AcrobatInstruction) {
22 CFX_XMLInstruction node(L"acrobat");
23 EXPECT_TRUE(node.IsAcrobat());
24 EXPECT_FALSE(node.IsOriginalXFAVersion());
25 }
26
TEST(CFX_XMLInstructionTest,OriginalXFAInstruction)27 TEST(CFX_XMLInstructionTest, OriginalXFAInstruction) {
28 CFX_XMLInstruction node(L"originalXFAVersion");
29 EXPECT_TRUE(node.IsOriginalXFAVersion());
30 EXPECT_FALSE(node.IsAcrobat());
31 }
32
TEST(CFX_XMLInstructionTest,TargetData)33 TEST(CFX_XMLInstructionTest, TargetData) {
34 CFX_XMLInstruction node(L"acrobat");
35 EXPECT_EQ(0U, node.GetTargetData().size());
36
37 node.AppendData(L"firstString");
38 node.AppendData(L"secondString");
39
40 auto& data = node.GetTargetData();
41 ASSERT_EQ(2U, data.size());
42 EXPECT_EQ(L"firstString", data[0]);
43 EXPECT_EQ(L"secondString", data[1]);
44 }
45
TEST(CFX_XMLInstructionTest,Clone)46 TEST(CFX_XMLInstructionTest, Clone) {
47 CFX_XMLDocument doc;
48
49 CFX_XMLInstruction node(L"acrobat");
50 node.AppendData(L"firstString");
51 node.AppendData(L"secondString");
52
53 CFX_XMLNode* clone = node.Clone(&doc);
54 EXPECT_TRUE(clone != nullptr);
55
56 ASSERT_EQ(CFX_XMLNode::Type::kInstruction, clone->GetType());
57 CFX_XMLInstruction* inst = ToXMLInstruction(clone);
58 EXPECT_TRUE(inst->IsAcrobat());
59
60 auto& data = inst->GetTargetData();
61 ASSERT_EQ(2U, data.size());
62 EXPECT_EQ(L"firstString", data[0]);
63 EXPECT_EQ(L"secondString", data[1]);
64 }
65
TEST(CFX_XMLInstructionTest,SaveXML)66 TEST(CFX_XMLInstructionTest, SaveXML) {
67 auto stream = pdfium::MakeRetain<StringWriteStream>();
68 CFX_XMLInstruction node(L"xml");
69 node.Save(stream);
70 EXPECT_EQ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", stream->ToString());
71 }
72
TEST(CFX_XMLInstructionTest,SaveAcrobat)73 TEST(CFX_XMLInstructionTest, SaveAcrobat) {
74 auto stream = pdfium::MakeRetain<StringWriteStream>();
75 CFX_XMLInstruction node(L"acrobat");
76 node.AppendData(L"http://www.xfa.org/schema/xfa-template/3.3/");
77 node.AppendData(L"Display:1");
78
79 node.Save(stream);
80 EXPECT_EQ(
81 "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n",
82 stream->ToString());
83 }
84
TEST(CFX_XMLInstructionTest,ParseAndReSave)85 TEST(CFX_XMLInstructionTest, ParseAndReSave) {
86 static const char input[] =
87 "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n"
88 "<node></node>";
89
90 auto in_stream = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(
91 pdfium::as_bytes(pdfium::make_span(input)));
92
93 CFX_XMLParser parser(in_stream);
94 std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
95 ASSERT_TRUE(doc != nullptr);
96
97 CFX_XMLElement* root = doc->GetRoot();
98 ASSERT_TRUE(root->GetFirstChild() != nullptr);
99 ASSERT_EQ(CFX_XMLNode::Type::kInstruction, root->GetFirstChild()->GetType());
100
101 CFX_XMLInstruction* node = ToXMLInstruction(root->GetFirstChild());
102 ASSERT_TRUE(node != nullptr);
103 EXPECT_TRUE(node->IsAcrobat());
104
105 auto& data = node->GetTargetData();
106 ASSERT_EQ(2U, data.size());
107 EXPECT_EQ(L"http://www.xfa.org/schema/xfa-template/3.3/", data[0]);
108 EXPECT_EQ(L"Display:1", data[1]);
109
110 auto out_stream = pdfium::MakeRetain<StringWriteStream>();
111 node->Save(out_stream);
112 EXPECT_EQ(
113 "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n",
114 out_stream->ToString());
115 }
116
TEST(CFX_XMLInstructionTest,ParseAndReSaveInnerInstruction)117 TEST(CFX_XMLInstructionTest, ParseAndReSaveInnerInstruction) {
118 static const char input[] =
119 "<node>\n"
120 "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n"
121 "</node>";
122
123 auto in_stream = pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(
124 pdfium::as_bytes(pdfium::make_span(input)));
125
126 CFX_XMLParser parser(in_stream);
127 std::unique_ptr<CFX_XMLDocument> doc = parser.Parse();
128 ASSERT_TRUE(doc != nullptr);
129
130 CFX_XMLElement* root = doc->GetRoot();
131 ASSERT_TRUE(root->GetFirstChild() != nullptr);
132 ASSERT_TRUE(root->GetFirstChild()->GetType() == CFX_XMLNode::Type::kElement);
133
134 CFX_XMLElement* node = ToXMLElement(root->GetFirstChild());
135 EXPECT_EQ(L"node", node->GetName());
136
137 CFX_XMLInstruction* instruction = nullptr;
138 for (auto* elem = node->GetFirstChild(); elem && !instruction;
139 elem = elem->GetNextSibling()) {
140 instruction = ToXMLInstruction(elem);
141 }
142 ASSERT_TRUE(instruction != nullptr);
143 EXPECT_TRUE(instruction->IsAcrobat());
144
145 auto& data = instruction->GetTargetData();
146 ASSERT_EQ(2U, data.size());
147 EXPECT_EQ(L"http://www.xfa.org/schema/xfa-template/3.3/", data[0]);
148 EXPECT_EQ(L"Display:1", data[1]);
149
150 auto out_stream = pdfium::MakeRetain<StringWriteStream>();
151 node->Save(out_stream);
152 EXPECT_EQ(
153 "<node>\n\n"
154 "<?acrobat http://www.xfa.org/schema/xfa-template/3.3/ Display:1 ?>\n\n"
155 "</node>\n",
156 out_stream->ToString());
157 }
158