[Libreoffice-commits] core.git: 2 commits - sc/Library_scqahelper.mk sc/qa sc/source

Markus Mohrhard markus.mohrhard at collabora.co.uk
Sat Jul 19 04:40:39 PDT 2014


 sc/Library_scqahelper.mk              |    2 
 sc/qa/unit/data/ods/fdo79305.ods      |binary
 sc/qa/unit/helper/qahelper.cxx        |   29 ++++++++
 sc/qa/unit/helper/qahelper.hxx        |    4 +
 sc/qa/unit/helper/xpath.cxx           |  116 ++++++++++++++++++++++++++++++++++
 sc/qa/unit/helper/xpath.hxx           |   77 ++++++++++++++++++++++
 sc/qa/unit/subsequent_export-test.cxx |   17 ++++
 sc/source/filter/xml/xmlexprt.cxx     |   14 ++++
 8 files changed, 259 insertions(+)

New commits:
commit 76d66256bb6825069f02e759983ef36df1404976
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Sat Jul 19 13:30:28 2014 +0200

    add test for fdo#79305
    
    Change-Id: I498f272e9da8c5f988e0bf734ffcc1c04b528210

diff --git a/sc/Library_scqahelper.mk b/sc/Library_scqahelper.mk
index 351b115..be7f230 100644
--- a/sc/Library_scqahelper.mk
+++ b/sc/Library_scqahelper.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_Library_use_externals,scqahelper, \
 	boost_headers \
 	mdds_headers \
 	cppunit \
+	libxml2 \
 ))
 
 ifneq ($(SYSTEM_LIBORCUS),)
@@ -59,6 +60,7 @@ $(eval $(call gb_Library_use_libraries,scqahelper,\
 
 $(eval $(call gb_Library_add_exception_objects,scqahelper,\
 	sc/qa/unit/helper/qahelper \
+	sc/qa/unit/helper/xpath \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/sc/qa/unit/data/ods/fdo79305.ods b/sc/qa/unit/data/ods/fdo79305.ods
new file mode 100644
index 0000000..c6f011c
Binary files /dev/null and b/sc/qa/unit/data/ods/fdo79305.ods differ
diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx
index 0b19843..6f02e9f 100644
--- a/sc/qa/unit/helper/qahelper.cxx
+++ b/sc/qa/unit/helper/qahelper.cxx
@@ -647,6 +647,35 @@ ScDocShellRef ScBootstrapFixture::saveAndReload( ScDocShell* pShell, sal_Int32 n
     return xDocSh;
 }
 
+boost::shared_ptr<utl::TempFile> ScBootstrapFixture::exportTo( ScDocShell* pShell, sal_Int32 nFormat )
+{
+    OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
+    OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
+
+    boost::shared_ptr<utl::TempFile> pTempFile(new utl::TempFile());
+    pTempFile->EnableKillingFile();
+    SfxMedium aStoreMedium( pTempFile->GetURL(), STREAM_STD_WRITE );
+    sal_uInt32 nExportFormat = 0;
+    sal_Int32 nFormatType = aFileFormats[nFormat].nFormatType;
+    if (nFormatType == ODS_FORMAT_TYPE)
+        nExportFormat = SFX_FILTER_EXPORT | SFX_FILTER_USESOPTIONS;
+    SfxFilter* pExportFilter = new SfxFilter(
+        aFilterName,
+        OUString(), nFormatType, nExportFormat, aFilterType, 0, OUString(),
+        OUString(), OUString("private:factory/scalc*") );
+    pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
+    aStoreMedium.SetFilter(pExportFilter);
+    pShell->DoSaveAs( aStoreMedium );
+    pShell->DoClose();
+
+    if(nFormatType == XLSX_FORMAT_TYPE)
+        validate(pTempFile->GetFileName(), test::OOXML);
+    else if (nFormatType == ODS_FORMAT_TYPE)
+        validate(pTempFile->GetFileName(), test::ODF);
+
+    return pTempFile;
+}
+
 void ScBootstrapFixture::miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems )
 {
     for ( unsigned int index=0; index<numElems; ++index )
diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx
index 8c96e36..30a655d 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -32,6 +32,8 @@
 
 #include <sal/types.h>
 
+#include <boost/shared_ptr.hpp>
+
 #if defined(SCQAHELPER_DLLIMPLEMENTATION)
 #define SCQAHELPER_DLLPUBLIC  SAL_DLLPUBLIC_EXPORT
 #else
@@ -244,6 +246,8 @@ public:
 
     ScDocShellRef saveAndReload( ScDocShell* pShell, sal_Int32 nFormat );
 
+    static boost::shared_ptr<utl::TempFile> exportTo( ScDocShell* pShell, sal_Int32 nFormat );
+
     void miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems );
 };
 
diff --git a/sc/qa/unit/helper/xpath.cxx b/sc/qa/unit/helper/xpath.cxx
new file mode 100644
index 0000000..875b7d0
--- /dev/null
+++ b/sc/qa/unit/helper/xpath.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "xpath.hxx"
+
+#include <cppunit/TestAssert.h>
+#include "qahelper.hxx"
+
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
+
+xmlDocPtr XPathHelper::parseExport(ScDocShell* pShell, uno::Reference<lang::XMultiServiceFactory> xSFactory, const OUString& rFile, sal_Int32 nFormat)
+{
+    boost::shared_ptr<utl::TempFile> pTempFile = ScBootstrapFixture::exportTo(pShell, nFormat);
+
+    // Read the XML stream we're interested in.
+    uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(xSFactory), pTempFile->GetURL());
+    uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(rFile), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xInputStream.is());
+    boost::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+    sal_uInt64 const nSize = pStream->remainingSize();
+    OStringBuffer aDocument(nSize);
+    char ch;
+    for (sal_Size i = 0; i < nSize; ++i)
+    {
+        pStream->ReadChar( ch );
+        aDocument.append(ch);
+    }
+    CPPUNIT_ASSERT(!aDocument.isEmpty());
+
+    // Parse the XML.
+    return xmlParseMemory((const char*)aDocument.getStr(), aDocument.getLength());
+}
+
+xmlNodeSetPtr XPathHelper::getXPathNode(xmlDocPtr pXmlDoc, const OString& rXPath)
+{
+    struct { xmlChar* pPrefix; xmlChar* pURI; } aNamespaces[] =
+    {
+        { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
+        { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
+        { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
+        { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
+        { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
+        { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
+        { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
+        { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
+        { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
+        { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
+        { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
+        { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") }
+    };
+    xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
+    for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
+    {
+        xmlXPathRegisterNs(pXmlXpathCtx, aNamespaces[i].pPrefix, aNamespaces[i].pURI );
+    }
+
+    xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(rXPath.getStr()), pXmlXpathCtx);
+    return pXmlXpathObj->nodesetval;
+}
+
+void XPathHelper::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute, const OUString& rExpectedValue)
+{
+    OUString aValue = getXPath(pXmlDoc, rXPath, rAttribute);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+            OString("Attribute '" + rAttribute + "' of '" + rXPath + "' incorrect value.").getStr(),
+            rExpectedValue, aValue);
+}
+
+void XPathHelper::assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, int nNumberOfNodes)
+{
+    xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+            OString("XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+            nNumberOfNodes, xmlXPathNodeSetGetLength(pXmlNodes));
+}
+
+void XPathHelper::assertXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath, const OUString& rContent)
+{
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("XPath contents of child does not match", rContent, getXPathContent(pXmlDoc, rXPath));
+}
+
+OUString XPathHelper::getXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath)
+{
+    xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath);
+
+    CPPUNIT_ASSERT_MESSAGE(OString("XPath '" + rXPath + "' not found").getStr(),
+            xmlXPathNodeSetGetLength(pXmlNodes) > 0);
+
+    xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+
+    _xmlNode *pNode = &(pXmlNode->children[0]);
+    return pNode ? OUString::createFromAscii((const char*)((pXmlNode->children[0]).content)) : OUString();
+}
+
+OUString XPathHelper::getXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute)
+{
+    xmlNodeSetPtr pXmlNodes = getXPathNode(pXmlDoc, rXPath);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+            OString("XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+            1, xmlXPathNodeSetGetLength(pXmlNodes));
+    if (rAttribute.isEmpty())
+        return OUString();
+    xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
+    return OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(rAttribute.getStr())));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/helper/xpath.hxx b/sc/qa/unit/helper/xpath.hxx
new file mode 100644
index 0000000..1a63401
--- /dev/null
+++ b/sc/qa/unit/helper/xpath.hxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_QA_UNIT_HELPER_XPATH_HXX
+#define INCLUDED_SC_QA_UNIT_HELPER_XPATH_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <libxml/xpathInternals.h>
+#include <libxml/parserInternals.h>
+
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+
+#if defined(SCQAHELPER_DLLIMPLEMENTATION)
+#define SCQAHELPER_DLLPUBLIC  SAL_DLLPUBLIC_EXPORT
+#else
+#define SCQAHELPER_DLLPUBLIC  SAL_DLLPUBLIC_IMPORT
+#endif
+
+#include "docsh.hxx"
+#include "scdllapi.h"
+
+using namespace com::sun::star;
+
+namespace XPathHelper
+{
+    /**
+     * Given that some problem doesn't affect the result in the importer, we
+     * test the resulting file directly, by opening the zip file, parsing an
+     * xml stream, and asserting an XPath expression. This method returns the
+     * xml stream, so that you can do the asserting.
+     */
+    SCQAHELPER_DLLPUBLIC xmlDocPtr parseExport(ScDocShell* pShell, uno::Reference< lang::XMultiServiceFactory> xSFactory,
+            const OUString& rFile, sal_Int32 nFormat);
+
+    /**
+     * Helper method to return nodes represented by rXPath.
+     */
+    SCQAHELPER_DLLPUBLIC xmlNodeSetPtr getXPathNode(xmlDocPtr pXmlDoc, const OString& rXPath);
+
+    /**
+     * Assert that rXPath exists, and returns exactly one node.
+     * In case rAttribute is provided, the rXPath's attribute's value must
+     * equal to the rExpected value.
+     */
+    SCQAHELPER_DLLPUBLIC void assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute = OString(), const OUString& rExpectedValue = OUString());
+
+    /**
+     * Assert that rXPath exists, and returns exactly nNumberOfNodes nodes.
+     * Useful for checking that we do _not_ export some node (nNumberOfNodes == 0).
+     */
+    SCQAHELPER_DLLPUBLIC void assertXPath(xmlDocPtr pXmlDoc, const OString& rXPath, int nNumberOfNodes);
+
+    /**
+     * Same as the assertXPath(), but don't assert: return the string instead.
+     */
+    SCQAHELPER_DLLPUBLIC OUString getXPath(xmlDocPtr pXmlDoc, const OString& rXPath, const OString& rAttribute);
+    /**
+    Assert that rXPath exists, and its content equals rContent.
+    */
+    SCQAHELPER_DLLPUBLIC void assertXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath, const OUString& rContent);
+    /**
+    Same as the assertXPathContent(), but don't assert: return the string instead.
+    */
+    SCQAHELPER_DLLPUBLIC OUString getXPathContent(xmlDocPtr pXmlDoc, const OString& rXPath);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index f91a2de..9517710 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -18,6 +18,7 @@
 #include <svl/stritem.hxx>
 
 #include "helper/qahelper.hxx"
+#include "helper/xpath.hxx"
 #include "helper/shared_test_impl.hxx"
 
 #include "docsh.hxx"
@@ -107,6 +108,8 @@ public:
     void testFunctionsExcel2010ODS();
 #endif
 
+    void testRelativePaths();
+
     CPPUNIT_TEST_SUITE(ScExportTest);
     CPPUNIT_TEST(test);
 #if !defined(MACOSX) && !defined(DRAGONFLY)
@@ -139,6 +142,7 @@ public:
     CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX);
     CPPUNIT_TEST(testFunctionsExcel2010XLSX);
     CPPUNIT_TEST(testFunctionsExcel2010XLS);
+    CPPUNIT_TEST(testRelativePaths);
 
     /* TODO: export to ODS currently (2014-04-28) makes the validator stumble,
      * probably due to a loext:fill-character attribute in a
@@ -1821,6 +1825,19 @@ void ScExportTest::testFunctionsExcel2010XLS()
     testFunctionsExcel2010(XLS);
 }
 
+void ScExportTest::testRelativePaths()
+{
+    ScDocShellRef xDocSh = loadDoc("fdo79305.", ODS);
+    CPPUNIT_ASSERT(xDocSh.Is());
+
+    xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "content.xml", ODS);
+    CPPUNIT_ASSERT(pDoc);
+    OUString aURL = XPathHelper::getXPath(pDoc,
+            "/office:document-content/office:body/office:spreadsheet/table:table/table:table-row[2]/table:table-cell[2]/text:p/text:a", "href");
+    // make sure that the URL is relative
+    CPPUNIT_ASSERT(aURL.startsWith(".."));
+}
+
 #if 0
 void ScExportTest::testFunctionsExcel2010ODS()
 {
commit 7c03aacb6746cc136f10acdc6ff8b146db62c8ad
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Fri Jul 18 20:31:09 2014 +0200

    respect flag for relative paths, fdo#79305
    
    Change-Id: I8f4e5f8f5e489d543f81b0b20255c875b83f7afc

diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 2b4cbef..70243eb 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -105,6 +105,7 @@
 #include <rtl/ustring.hxx>
 
 #include <tools/color.hxx>
+#include <tools/urlobj.hxx>
 #include <rtl/math.hxx>
 #include <svl/zforlist.hxx>
 #include <svx/unoshape.hxx>
@@ -117,6 +118,9 @@
 #include <svx/svdpage.hxx>
 #include <svtools/miscopt.hxx>
 
+#include <officecfg/Office/Common.hxx>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
 #include <comphelper/processfactory.hxx>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/container/XNamed.hpp>
@@ -3080,7 +3084,17 @@ void writeContent(
             {
                 // <text:a xlink:href="url" xlink:type="simple">value</text:a>
 
+                Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+                bool bUseRelative = officecfg::Office::Common::Save::URL::FileSystem::get( xContext );
                 OUString aURL = static_cast<const SvxURLField*>(pField)->GetURL();
+                if(bUseRelative)
+                {
+                    OUString aBase = rExport.GetOrigFileName();
+                    INetURLObject aURLObject(aBase);
+                    aURLObject.removeSegment();
+                    aURLObject.removeSegment();
+                    aURL = INetURLObject::GetRelURL(aURLObject.GetMainURL(INetURLObject::DECODE_TO_IURI), aURL);
+                }
                 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aURL);
                 rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, "simple");
 


More information about the Libreoffice-commits mailing list