nss: upgrade to release 3.73
[LibreOffice.git] / test / source / xmltesttools.cxx
blob27833af1e90d9f1823f35f05a5d9533def7aa40d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <test/xmltesttools.hxx>
12 #include <memory>
14 #include <vcl/mtfxmldump.hxx>
15 #include <sal/log.hxx>
17 namespace {
19 OUString convert(xmlChar const * string) {
20 OUString s;
21 CPPUNIT_ASSERT_MESSAGE(
22 "xmlChar string is not UTF-8",
23 rtl_convertStringToUString(
24 &s.pData, reinterpret_cast<char const *>(string), xmlStrlen(string),
25 RTL_TEXTENCODING_UTF8,
26 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
27 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
28 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)));
29 return s;
32 OString oconvert(xmlChar const * string)
34 return reinterpret_cast<char const *>(string);
39 XmlTestTools::XmlTestTools()
42 XmlTestTools::~XmlTestTools()
45 xmlDocUniquePtr XmlTestTools::parseXml(utl::TempFile const & aTempFile)
47 SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
48 return parseXmlStream(&aFileStream);
51 xmlDocUniquePtr XmlTestTools::parseXmlStream(SvStream* pStream)
53 std::size_t nSize = pStream->remainingSize();
54 std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nSize + 1]);
55 pStream->ReadBytes(pBuffer.get(), nSize);
56 pBuffer[nSize] = 0;
57 auto pCharBuffer = reinterpret_cast<xmlChar*>(pBuffer.get());
58 SAL_INFO("test", "XmlTestTools::parseXmlStream: pBuffer is '" << pCharBuffer << "'");
59 return xmlDocUniquePtr(xmlParseDoc(pCharBuffer));
62 xmlDocUniquePtr XmlTestTools::dumpAndParse(MetafileXmlDump& rDumper, const GDIMetaFile& rGDIMetaFile)
64 SvMemoryStream aStream;
65 rDumper.dump(rGDIMetaFile, aStream);
66 aStream.Seek(STREAM_SEEK_TO_BEGIN);
67 return XmlTestTools::parseXmlStream(&aStream);
70 xmlXPathObjectPtr XmlTestTools::getXPathNode(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
72 xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc.get());
73 registerNamespaces(pXmlXpathCtx);
74 xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(rXPath.getStr()), pXmlXpathCtx);
75 xmlXPathFreeContext(pXmlXpathCtx);
76 return pXmlXpathObj;
79 void XmlTestTools::registerNamespaces(xmlXPathContextPtr& /*pXmlXpathCtx*/)
83 OUString XmlTestTools::getXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute)
85 CPPUNIT_ASSERT(pXmlDoc);
86 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
87 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
88 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
89 1, xmlXPathNodeSetGetLength(pXmlNodes));
90 if (rAttribute.isEmpty())
92 xmlXPathFreeObject(pXmlObj);
93 return OUString();
95 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
96 xmlChar * prop = xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr()));
97 OString sAttAbsent = OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath
98 + "' no attribute '" + rAttribute + "' exist";
99 CPPUNIT_ASSERT_MESSAGE(sAttAbsent.getStr(), prop);
100 OUString s(convert(prop));
101 xmlFree(prop);
102 xmlXPathFreeObject(pXmlObj);
103 return s;
106 OUString XmlTestTools::getXPathContent(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
108 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
109 switch (pXmlObj->type)
111 case XPATH_UNDEFINED:
112 CPPUNIT_FAIL("Undefined XPath type");
113 case XPATH_NODESET:
115 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
117 CPPUNIT_ASSERT_MESSAGE(
118 OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' not found")
119 .getStr(),
120 xmlXPathNodeSetGetLength(pXmlNodes) > 0);
122 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
123 xmlNodePtr pXmlChild = pXmlNode->children;
124 OUString s;
125 while (pXmlChild && pXmlChild->type != XML_TEXT_NODE)
126 pXmlChild = pXmlChild->next;
127 if (pXmlChild && pXmlChild->type == XML_TEXT_NODE)
128 s = convert(pXmlChild->content);
129 xmlXPathFreeObject(pXmlObj);
130 return s;
132 case XPATH_BOOLEAN:
134 auto boolVal = pXmlObj->boolval;
135 xmlXPathFreeObject(pXmlObj);
136 return boolVal ? OUString("true") : OUString("false");
138 case XPATH_NUMBER:
140 auto floatVal = pXmlObj->floatval;
141 xmlXPathFreeObject(pXmlObj);
142 return OUString::number(floatVal);
144 case XPATH_STRING:
146 auto convertedVal = convert(pXmlObj->stringval);
147 xmlXPathFreeObject(pXmlObj);
148 return convertedVal;
150 case XPATH_POINT:
151 case XPATH_RANGE:
152 case XPATH_LOCATIONSET:
153 case XPATH_USERS:
154 case XPATH_XSLT_TREE:
155 xmlXPathFreeObject(pXmlObj);
156 CPPUNIT_FAIL("Unsupported XPath type");
159 CPPUNIT_FAIL("Invalid XPath type");
162 void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
164 getXPath(pXmlDoc, rXPath, ""); // it asserts that rXPath exists, and returns exactly one node
167 void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute, const OUString& rExpectedValue)
169 OUString aValue = getXPath(pXmlDoc, rXPath, rAttribute);
170 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, attribute '" + rAttribute + "' of '" + rXPath + "' incorrect value.").getStr(),
171 rExpectedValue, aValue);
174 void XmlTestTools::assertXPathAttrs(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath,
175 const std::vector<std::pair<OString, OUString>>& aPairVector)
177 for (auto& rPair : aPairVector)
179 assertXPath(pXmlDoc, rXPath, rPair.first, rPair.second);
183 void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfNodes)
185 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
186 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
187 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
188 nNumberOfNodes, xmlXPathNodeSetGetLength(pXmlNodes));
189 xmlXPathFreeObject(pXmlObj);
192 void XmlTestTools::assertXPathContent(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OUString& rContent)
194 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath contents of child does not match").getStr(), rContent, getXPathContent(pXmlDoc, rXPath));
197 void XmlTestTools::assertXPathNSDef(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath,
198 const OUString& rNSPrefix, const OUString& rNSHref)
200 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
201 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
202 CPPUNIT_ASSERT_MESSAGE(
203 OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' not found").getStr(),
204 xmlXPathNodeSetGetLength(pXmlNodes) > 0);
206 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
207 bool bFound = false;
208 for (xmlNsPtr pNamespace = pXmlNode->nsDef; pNamespace; pNamespace = pNamespace->next)
210 if (!pNamespace->prefix)
211 continue;
213 CPPUNIT_ASSERT(pNamespace->href);
214 if (rNSPrefix == convert(pNamespace->prefix) && rNSHref == convert(pNamespace->href))
216 bFound = true;
217 break;
220 xmlXPathFreeObject(pXmlObj);
221 CPPUNIT_ASSERT(bFound);
224 void XmlTestTools::assertXPathChildren(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfChildNodes)
226 #if LIBXML_VERSION >= 20703 /* xmlChildElementCount is only available in libxml2 >= 2.7.3 */
227 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
228 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
229 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
230 1, xmlXPathNodeSetGetLength(pXmlNodes));
231 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
232 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of child-nodes is incorrect").getStr(),
233 nNumberOfChildNodes, static_cast<int>(xmlChildElementCount(pXmlNode)));
234 xmlXPathFreeObject(pXmlObj);
235 #else
236 (void)pXmlDoc;
237 (void)rXPath;
238 (void)nNumberOfChildNodes;
239 #endif
242 void XmlTestTools::assertXPathNoAttribute(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rAttribute)
244 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
245 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
246 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
247 1, xmlXPathNodeSetGetLength(pXmlNodes));
248 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
249 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' unexpected '" + rAttribute + "' attribute").getStr(),
250 static_cast<xmlChar*>(nullptr), xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr())));
251 xmlXPathFreeObject(pXmlObj);
254 int XmlTestTools::getXPathPosition(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OString& rChildName)
256 xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
257 xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
258 CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
260 xmlXPathNodeSetGetLength(pXmlNodes));
261 xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
262 int nRet = 0;
263 bool bFound = false;
264 for (xmlNodePtr pChild = pXmlNode->children; pChild; pChild = pChild->next)
266 if (oconvert(pChild->name) == rChildName)
268 bFound = true;
269 break;
271 ++nRet;
273 xmlXPathFreeObject(pXmlObj);
274 CPPUNIT_ASSERT_MESSAGE(OString(OStringLiteral("In <") + pXmlDoc->name + ">, XPath '" + rXPath
275 + "' child '" + rChildName + "' not found")
276 .getStr(),
277 bFound);
278 return nRet;
281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */