summaryrefslogtreecommitdiff
path: root/xmloff/qa/unit
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-03-11 13:01:16 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-03-11 16:14:57 +0100
commit08e783903cf67e9c6673e21f99dfff816f8d5872 (patch)
treeea359afb12e7b112ce3324dd2fa021c506ffb39f /xmloff/qa/unit
parentf92510321dc860f43e471473db67167c0fefcbea (diff)
ODF export: sort <style:font-face> elements based on the style:name attribute
m_pFontAutoStylePool is already sorted, but sorting ignores XMLFontAutoStylePoolEntry_Impl::sName, and changing XMLFontAutoStylePoolEntryCmp_Impl would affect how find() works in XMLFontAutoStylePool::Add(), so just extend XMLFontAutoStylePool::exportXML() instead. With this, the order of <style:font-face> elements is meant to be stable in content.xml and styles.xml, helping use-cases where a document is converted to ODF multiple times and an integration test wants to assert that the output is the same. Change-Id: If0dbfa40a1b204aebe5e141fe64f71ac2ca92405 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112339 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'xmloff/qa/unit')
-rw-r--r--xmloff/qa/unit/style.cxx69
1 files changed, 68 insertions, 1 deletions
diff --git a/xmloff/qa/unit/style.cxx b/xmloff/qa/unit/style.cxx
index f2d9cdbedc37..eaae3bbd1b92 100644
--- a/xmloff/qa/unit/style.cxx
+++ b/xmloff/qa/unit/style.cxx
@@ -13,16 +13,25 @@
#include <test/bootstrapfixture.hxx>
#include <unotest/macros_test.hxx>
+#include <test/xmltesttools.hxx>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
+
+#include <comphelper/propertysequence.hxx>
+#include <unotools/tempfile.hxx>
+#include <unotools/ucbstreamhelper.hxx>
using namespace ::com::sun::star;
constexpr OUStringLiteral DATA_DIRECTORY = u"/xmloff/qa/unit/data/";
/// Covers xmloff/source/style/ fixes.
-class XmloffStyleTest : public test::BootstrapFixture, public unotest::MacrosTest
+class XmloffStyleTest : public test::BootstrapFixture,
+ public unotest::MacrosTest,
+ public XmlTestTools
{
private:
uno::Reference<lang::XComponent> mxComponent;
@@ -30,6 +39,7 @@ private:
public:
void setUp() override;
void tearDown() override;
+ void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override;
uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
void load(std::u16string_view rURL);
};
@@ -49,6 +59,14 @@ void XmloffStyleTest::tearDown()
test::BootstrapFixture::tearDown();
}
+void XmloffStyleTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
+{
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("office"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("style"),
+ BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0"));
+}
+
void XmloffStyleTest::load(std::u16string_view rFileName)
{
OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + rFileName;
@@ -68,6 +86,55 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFillImageBase64)
CPPUNIT_ASSERT(xBitmaps->hasByName("libreoffice_0"));
}
+CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFontSorting)
+{
+ // Given an empty document with default fonts (Liberation Sans, Lucida Sans, etc):
+ getComponent() = loadFromDesktop("private:factory/swriter");
+
+ // When saving that document to ODT:
+ uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY);
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ uno::Sequence<beans::PropertyValue> aStoreProps = comphelper::InitPropertySequence({
+ { "FilterName", uno::makeAny(OUString("writer8")) },
+ });
+ xStorable->storeToURL(aTempFile.GetURL(), aStoreProps);
+
+ // Then make sure <style:font-face> elements are sorted (by style:name="..."):
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess
+ = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, aTempFile.GetURL());
+ uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName("content.xml"),
+ uno::UNO_QUERY);
+ std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+ xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
+ xmlXPathObjectPtr pXPath
+ = getXPathNode(pXmlDoc, "/office:document-content/office:font-face-decls/style:font-face");
+ xmlNodeSetPtr pXmlNodes = pXPath->nodesetval;
+ int nNodeCount = xmlXPathNodeSetGetLength(pXmlNodes);
+ std::vector<OString> aXMLNames;
+ std::set<OString> aSortedNames;
+ for (int i = 0; i < nNodeCount; ++i)
+ {
+ xmlNodePtr pXmlNode = pXmlNodes->nodeTab[i];
+ xmlChar* pName = xmlGetProp(pXmlNode, BAD_CAST("name"));
+ OString aName(reinterpret_cast<char const*>(pName));
+ aXMLNames.push_back(aName);
+ aSortedNames.insert(aName);
+ xmlFree(pName);
+ }
+ size_t nIndex = 0;
+ for (const auto& rName : aSortedNames)
+ {
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Liberation Sans
+ // - Actual : Lucida Sans1
+ // i.e. the output was not lexicographically sorted, "u" was before "i".
+ CPPUNIT_ASSERT_EQUAL(rName, aXMLNames[nIndex]);
+ ++nIndex;
+ }
+ xmlXPathFreeObject(pXPath);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */