summaryrefslogtreecommitdiffstats
path: root/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sw/qa/extras/ooxmlexport/ooxmlexport.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/qa/extras/ooxmlexport/ooxmlexport.cxx')
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx1066
1 files changed, 1066 insertions, 0 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
new file mode 100644
index 000000000..0ea9cc9f7
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -0,0 +1,1066 @@
+/* -*- 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 <swmodeltestbase.hxx>
+
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/text/FontEmphasis.hpp>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
+#include <com/sun/star/text/WritingMode2.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <o3tl/cppunittraitshelper.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+
+class Test : public SwModelTestBase
+{
+public:
+ Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
+
+protected:
+ /**
+ * Blacklist handling
+ */
+ bool mustTestImportOf(const char* filename) const override {
+ const char* aBlacklist[] = {
+ "math-escape.docx",
+ "math-mso2k7.docx",
+ };
+ std::vector<const char*> vBlacklist(aBlacklist, aBlacklist + SAL_N_ELEMENTS(aBlacklist));
+
+ // If the testcase is stored in some other format, it's pointless to test.
+ return (OString(filename).endsWith(".docx") && std::find(vBlacklist.begin(), vBlacklist.end(), filename) == vBlacklist.end());
+ }
+
+ /**
+ * Validation handling
+ */
+ bool mustValidate(const char* filename) const override
+ {
+ const char* aWhitelist[] = {
+ "paragraph-mark-nonempty.odt"
+ };
+ std::vector<const char*> vWhitelist(aWhitelist, aWhitelist + SAL_N_ELEMENTS(aWhitelist));
+
+ return std::find(vWhitelist.begin(), vWhitelist.end(), filename) != vWhitelist.end();
+ }
+};
+
+DECLARE_OOXMLEXPORT_TEST(testfdo81381, "fdo81381.docx")
+{
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/w:object[1]/o:OLEObject[1]", "DrawAspect", "Icon");
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testSdtAlias, "sdt-alias.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+
+ // <w:alias> was completely missing.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:alias", "val", "Subtitle");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testFooterBodyDistance, "footer-body-distance.docx")
+{
+ if (xmlDocUniquePtr pXmlDoc = parseExport())
+ // Page break was exported as section break, this was 0
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1);
+}
+
+// Check for correct header/footer with special first page with TOC inside:
+// - DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt")
+// - DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt")
+DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt")
+{
+ CPPUNIT_ASSERT_EQUAL( 7, getPages() );
+
+ // First page has no header/footer
+ {
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // check first page
+ xmlXPathObjectPtr pXmlPage1Header = getXPathNode(pXmlDoc, "/root/page[1]/header");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Header->nodesetval));
+
+ xmlXPathObjectPtr pXmlPage1Footer = getXPathNode(pXmlDoc, "/root/page[1]/footer");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Footer->nodesetval));
+
+ // check second page in the same way
+ xmlXPathObjectPtr pXmlPage2Header = getXPathNode(pXmlDoc, "/root/page[2]/header");
+ CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Header->nodesetval));
+
+ xmlXPathObjectPtr pXmlPage2Footer = getXPathNode(pXmlDoc, "/root/page[2]/footer");
+ CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Footer->nodesetval));
+ }
+
+ // All other pages should have header/footer
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[2]/footer/txt/text()"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[3]/footer/txt/text()"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[4]/footer/txt/text()"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[5]/footer/txt/text()"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[6]/footer/txt/text()"));
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"), parseDump("/root/page[7]/footer/txt/text()"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testfdo81031, "fdo81031.docx")
+{
+ // vml image was not rendered
+ // As there are also numPicBullets in the file,
+ // the fragmentPath was not changed hence relationships were not resolved.
+
+ uno::Reference<drawing::XShape> image = getShape(1);
+ uno::Reference<beans::XPropertySet> xImage(image, uno::UNO_QUERY);
+ uno::Reference<graphic::XGraphic> xGraphic = getProperty<uno::Reference<graphic::XGraphic> >(xImage, "Graphic");
+ uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(381), xBitmap->getSize().Width );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(148), xBitmap->getSize().Height );
+}
+
+DECLARE_OOXMLEXPORT_TEST(testPlausableBorder, "plausable-border.docx")
+{
+ // sw::util::IsPlausableSingleWordSection() did not merge two page styles due to borders.
+ if (xmlDocUniquePtr pXmlDoc = parseExport())
+ // Page break was exported as section break, this was 0
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1);
+
+ CPPUNIT_ASSERT_EQUAL( 2, getPages() );
+}
+
+DECLARE_OOXMLEXPORT_TEST(testUnwantedSectionBreak, "unwanted-section-break.docx")
+{
+ if (xmlDocUniquePtr pXmlDoc = parseExport())
+ // This was 2: an additional sectPr was added to the document.
+ assertXPath(pXmlDoc, "//w:sectPr", 1);
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testfdo80897 , "fdo80897.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:bodyPr/a:prstTxWarp", "prst", "textTriangle");
+}
+
+
+DECLARE_OOXMLEXPORT_TEST(testFdo80997, "fdo80997.docx")
+{
+ // The problem was that the DOCX exporter not able to export text behind textbox, if textbox has a wrap property.
+ uno::Reference< text::XTextRange > xParagraph = getParagraph( 1 );
+ getRun( xParagraph, 1, " text");
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFdo80902, "fdo80902.docx")
+{
+ // The problem was that the docGrid type was set as default so fix it for other grid type
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:docGrid", "type", "lines");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testParaShading, "para-shading.docx")
+{
+ // Make sure the themeColor attribute is not written when it would be empty.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:shd", "themeColor");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testFirstHeaderFooter, "first-header-footer.docx")
+{
+ // Test import and export of a section's headerf/footerf properties.
+ // (copied from a ww8export test, with doc converted to docx using Word)
+
+ CPPUNIT_ASSERT_EQUAL( 6, getPages() );
+
+ // The document has 6 pages. Note that we don't test if 4 or just 2 page
+ // styles are created, the point is that layout should be correct.
+ CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("First page footer"), parseDump("/root/page[1]/footer/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Even page header"), parseDump("/root/page[2]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Even page footer"), parseDump("/root/page[2]/footer/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Odd page header"), parseDump("/root/page[3]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer"), parseDump("/root/page[3]/footer/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("First page header2"), parseDump("/root/page[4]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("First page footer 2"), parseDump("/root/page[4]/footer/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Odd page header 2"), parseDump("/root/page[5]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer 2"), parseDump("/root/page[5]/footer/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Even page header 2"), parseDump("/root/page[6]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Even page footer 2"), parseDump("/root/page[6]/footer/txt/text()"));
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testFDO83044, "fdo83044.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:text", 1);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testfdo83428, "fdo83428.docx")
+{
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xProps(xDocumentPropertiesSupplier->getDocumentProperties());
+ uno::Reference<beans::XPropertySet> xUDProps(xProps->getUserDefinedProperties(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Document"), getProperty<OUString>(xUDProps, "Testing"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testShapeInFloattable, "shape-in-floattable.docx")
+{
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ // No nested drawingML w:txbxContent.
+ assertXPath(pXmlDoc, "//mc:Choice//w:txbxContent//w:txbxContent", 0);
+ // Instead, make sure we have a separate shape and a table
+ assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wpg']", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl", 1);
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testEmptyAnnotationMark, "empty-annotation-mark.docx")
+{
+ if (mbExported)
+ {
+ // Delete the word that is commented, and save again.
+ uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1), 3);
+ CPPUNIT_ASSERT_EQUAL(OUString("with"), xRun->getString());
+ xRun->setString("");
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ xStorable->store();
+
+ // Then inspect the OOXML markup of the modified document model.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ // There were two commentReference nodes.
+ assertXPath(pXmlDoc, "//w:commentReference", "id", "0");
+ // Empty comment range was not ignored on export, this was 1.
+ assertXPath(pXmlDoc, "//w:commentRangeStart", 0);
+ // Ditto.
+ assertXPath(pXmlDoc, "//w:commentRangeEnd", 0);
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testDropdownInCell, "dropdown-in-cell.docx")
+{
+ // First problem: table was missing from the document, this was 0.
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+ // Second problem: dropdown shape wasn't anchored inside the B1 cell.
+ if (getShapes() > 0)
+ {
+ uno::Reference<text::XTextContent> xShape(getShape(1), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xAnchor = xShape->getAnchor();
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("B1"), uno::UNO_QUERY);
+ uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xCell, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextRangeCompare->compareRegionStarts(xAnchor, xCell));
+ }
+ else
+ {
+ // ComboBox was imported as DropDown text field
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+ uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+ CPPUNIT_ASSERT(xFields->hasMoreElements());
+ uno::Any aField = xFields->nextElement();
+ uno::Reference<lang::XServiceInfo> xServiceInfo(aField, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.textfield.DropDown"));
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTableAlignment, "table-alignment.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ // This was LEFT_AND_WIDTH, i.e. table alignment wasn't imported correctly.
+ CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xTable, "HoriOrient"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testSdtIgnoredFooter, "sdt-ignored-footer.docx")
+{
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ // This was 1, make sure no w:sdt sneaks into the main document from the footer.
+ assertXPath(pXmlDoc, "//w:sdt", 0);
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testSdtRunPicture, "sdt-run-picture.docx")
+{
+ // SDT around run was exported as SDT around paragraph
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ // This was 1: there was an SDT around w:p.
+ assertXPath(pXmlDoc, "//w:body/w:sdt", 0);
+ // This was 0: there were no SDT around w:r.
+ assertXPath(pXmlDoc, "//w:body/w:p/w:sdt", 1);
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testChartDupe, "chart-dupe.docx")
+{
+ // Single chart was exported back as two charts.
+ uno::Reference<text::XTextEmbeddedObjectsSupplier> xTextEmbeddedObjectsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xEmbeddedObjects(xTextEmbeddedObjectsSupplier->getEmbeddedObjects(), uno::UNO_QUERY);
+ // This was 2, on second import we got a duplicated chart copy.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xEmbeddedObjects->getCount());
+
+ xmlDocUniquePtr pXmlDocCT = parseExport("[Content_Types].xml");
+
+ if (!pXmlDocCT)
+ return; // initial import
+
+ assertXPath(pXmlDocCT,
+ "/ContentType:Types/ContentType:Override[@PartName='/word/charts/chart1.xml']",
+ "ContentType",
+ "application/vnd.openxmlformats-officedocument.drawingml.chart+xml");
+ assertXPath(pXmlDocCT, "/ContentType:Types/ContentType:Override[@PartName='/word/embeddings/Microsoft_Excel_Worksheet1.xlsx']", "ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+
+ // check the rels too
+ xmlDocUniquePtr pXmlDocRels = parseExport("word/charts/_rels/chart1.xml.rels");
+ assertXPath(pXmlDocRels,
+ "/rels:Relationships/rels:Relationship[@Target='../embeddings/Microsoft_Excel_Worksheet1.xlsx']",
+ "Type",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package");
+ // check the content too
+ xmlDocUniquePtr pXmlDocChart1 = parseExport("word/charts/chart1.xml");
+ assertXPath(pXmlDocChart1,
+ "/c:chartSpace/c:externalData",
+ "id",
+ "rId1");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testPositionAndRotation, "position-and-rotation.docx")
+{
+ // The document should look like: "This line is tricky, <image> because only 'This line is tricky,' is on the left."
+ // But the image was pushed down, so it did not break the line into two text portions.
+ uno::Reference<drawing::XShape> xShape = getShape(1);
+ // Should be 1559, was -5639
+ CPPUNIT_ASSERT(xShape->getPosition().X > 1500);
+ // Should be 88, was 473
+ CPPUNIT_ASSERT(xShape->getPosition().Y < 100);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testNumberingFont, "numbering-font.docx")
+{
+ // check that the original numrule font name is still Calibri
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("CharacterStyles")->getByName("ListLabel 1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Calibri"), getProperty<OUString>(xStyle, "CharFontName"));
+
+ uno::Reference<text::XTextRange> xPara = getParagraph(2);
+ uno::Reference<beans::XPropertySet> properties(xPara, uno::UNO_QUERY);
+ uno::Any aValue = properties->getPropertyValue("ListAutoFormat");
+ CPPUNIT_ASSERT(aValue.hasValue());
+ uno::Sequence<beans::NamedValue> aListAutoFormat;
+ CPPUNIT_ASSERT(aValue >>= aListAutoFormat);
+ auto it = std::find_if(std::cbegin(aListAutoFormat), std::cend(aListAutoFormat),
+ [](const css::beans::NamedValue& val) { return val.Name == "CharFontName"; });
+ CPPUNIT_ASSERT(it != std::cend(aListAutoFormat));
+ OUString sOverrideFontName;
+ CPPUNIT_ASSERT(it->Value >>= sOverrideFontName);
+ // but the overridden font name is Verdana
+ CPPUNIT_ASSERT_EQUAL(OUString("Verdana"), sOverrideFontName);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf106541_noinheritChapterNumbering, "tdf106541_noinheritChapterNumbering.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ // in LO, it appears that styles based on the Chapter Numbering style explicitly set the
+ // numbering style/outline level to 0 by default, and that LO prevents inheriting directly from "Outline" style.
+ // Adding this preventative unit test to ensure that any fix for tdf106541 doesn't make incorrect assumptions.
+
+//reverting tdf#76817 hard-codes the numbering style on the paragraph, preventing RT of "Outline" style
+// CPPUNIT_ASSERT_EQUAL(OUString("Outline"), getProperty<OUString>(getParagraph(1), "NumberingStyleName"));
+
+ OUString sPara3NumberingStyle = getProperty<OUString>(getParagraph(3), "NumberingStyleName");
+ CPPUNIT_ASSERT_EQUAL(sPara3NumberingStyle, getProperty<OUString>(getParagraph(4), "NumberingStyleName"));
+
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//body/txt/Special", 3); //three of the four paragraphs have numbering
+ assertXPath(pXmlDoc, "//body/txt[1]/Special", "rText", "1");
+ assertXPath(pXmlDoc, "//body/txt[2]/Special", 0); //second paragraph style disables numbering
+ assertXPath(pXmlDoc, "//body/txt[3]/Special", "rText", "I.");
+ assertXPath(pXmlDoc, "//body/txt[4]/Special", "rText", "II.");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf53856_conflictingStyle, "tdf53856_conflictingStyle.docx")
+{
+ // The "Text" style conflicted with builtin paragraph style Caption -> Text
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Text"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Times New Roman"), getProperty<OUString>(xStyle, "CharFontName"));
+ CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xStyle, "CharPosture"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf104713_undefinedStyles, "tdf104713_undefinedStyles.docx")
+{
+ // Normal paragraph style was not defined, so don't replace conflicting styles
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Heading 1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), getProperty<sal_Int32>(xStyle, "ParaBottomMargin"));
+
+ // tdf108765: once importing is finished, use default values for any styles not yet defined.
+ xStyle.set( getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, getProperty<float>(xStyle, "CharHeight"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testDrawingmlFlipv, "drawingml-flipv.docx")
+{
+ // The problem was that the shape had vertical flip only, but then we added rotation as well on export.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ assertXPathNoAttribute(pXmlDoc, "//a:xfrm", "rot");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testRot90Fliph, "rot90-fliph.docx")
+{
+ // The problem was that a shape rotation of 90° got turned into 270° after roundtrip.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ assertXPath(pXmlDoc, "//a:xfrm", "flipH", "1");
+ // This was 16200000 (270 * 60000).
+ assertXPath(pXmlDoc, "//a:xfrm", "rot", "5400000");
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testRot180Flipv, "rot180-flipv.docx")
+{
+ // 180° rotation got lost after roundtrip.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1");
+ // This attribute was completely missing.
+ assertXPath(pXmlDoc, "//a:xfrm", "rot", "10800000");
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testRot270Flipv, "rot270-flipv.docx")
+{
+ // 270° rotation got turned into 90° after roundtrip.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1");
+ // This was 5400000.
+ assertXPath(pXmlDoc, "//a:xfrm", "rot", "16200000");
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testMsoPosition, "bnc884615-mso-position.docx")
+{
+ if(xmlDocUniquePtr doc = parseExport("word/footer1.xml"))
+ {
+ // We write the frames out in different order than they were read, so check it's the correct
+ // textbox first by checking width. These tests may need reordering if that gets fixed.
+ OUString style1 = getXPath(doc, "/w:ftr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style1.indexOf( ";width:531pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
+ CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
+ OUString style2 = getXPath(doc, "/w:ftr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style2.indexOf( ";width:549pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:text" ) >= 0 );
+ CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal:center" ) >= 0 );
+ CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 );
+ OUString style3 = getXPath(doc, "/w:ftr/w:p/w:r[5]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style3.indexOf( ";width:36pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 );
+ CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:text" ) >= 0 );
+ }
+
+ xmlDocUniquePtr doc = parseExport("word/header1.xml");
+ if(!doc)
+ return;
+
+ OUString style1 = getXPath(doc, "/w:hdr/w:p/w:r[2]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style1.indexOf( ";width:335.75pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
+ CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
+ OUString style2 = getXPath(doc, "/w:hdr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style2.indexOf( ";width:138.15pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
+ CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
+ OUString style3 = getXPath(doc, "/w:hdr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
+ CPPUNIT_ASSERT( style3.indexOf( ";width:163.8pt;" ) >= 0 );
+ CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
+ CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
+
+}
+
+DECLARE_OOXMLEXPORT_TEST(testWpsCharColor, "wps-char-color.docx")
+{
+ uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
+ // This was -1, i.e. the character color was default (-1), not white.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xShape->getStart(), "CharColor"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTableStyleCellBackColor, "table-style-cell-back-color.docx")
+{
+ // The problem was that cell background was white, not green.
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<table::XCell> xCell = xTable->getCellByName("A1");
+ // This was 0xffffff.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00ff00), getProperty<sal_Int32>(xCell, "BackColor"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTableStyleBorder, "table-style-border.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+
+ // This was 0, the second cell was missing its right border.
+ uno::Reference<table::XCell> xCell = xTable->getCellByName("A2");
+ CPPUNIT_ASSERT(getProperty<table::BorderLine2>(xCell, "RightBorder").LineWidth > 0);
+
+ // This was also 0 (even after fixing the previous problem), the first cell was missing its right border, too.
+ xCell = xTable->getCellByName("A1");
+ CPPUNIT_ASSERT(getProperty<table::BorderLine2>(xCell, "RightBorder").LineWidth > 0);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTableStyleBorderExport, "table-style-border-export.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<table::XCell> xCell = xTable->getCellByName("A3");
+ // Bottom border was white, so this was 0xffffff.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0x8064A2), getProperty<table::BorderLine2>(xCell, "BottomBorder").Color);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testAnchorPosition, "anchor-position.docx")
+{
+ // The problem was that the at-char anchored picture was at the end of the
+ // paragraph, so there were only two positions: a Text, then a Frame one.
+ CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(getRun(getParagraph(1), 1), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty<OUString>(getRun(getParagraph(1), 2), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(getRun(getParagraph(1), 3), "TextPortionType"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testMultiPageToc, "multi-page-toc.docx")
+{
+ // Import of this document triggered an STL assertion.
+
+ // Document has a ToC from its second paragraph.
+ uno::Reference<container::XNamed> xTextSection = getProperty< uno::Reference<container::XNamed> >(getParagraph(2), "TextSection");
+ CPPUNIT_ASSERT_EQUAL(OUString("Table of Contents1"), xTextSection->getName());
+ // There should be a field in the header as well.
+ uno::Reference<text::XText> xHeaderText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName("Standard"), "HeaderText");
+ CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), "TextPortionType"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTextboxTable, "textbox-table.docx")
+{
+ // We wrote not-well-formed XML during export for this one:
+ // Shape with textbox, having a table and also anchored inside a table.
+
+ // Just make sure that we have both tables.
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testCropPixel, "crop-pixel.docx")
+{
+ // If map mode of the graphic is in pixels, then we used to handle original
+ // size of the graphic as mm100, but it was in pixels.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ // This is 17667 in the original document, was 504666 (so the image
+ // become invisible), now is around 19072.
+ CPPUNIT_ASSERT(getXPath(pXmlDoc, "//a:srcRect", "l").toInt32() <= 22452);
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testEffectExtent, "effect-extent.docx")
+{
+ // The problem was that in case there were no shadows on the picture, we
+ // wrote a <wp:effectExtent> full or zeros.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ // E.g. this was 0.
+ assertXPath(pXmlDoc, "//wp:effectExtent", "l", "114300");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testEffectExtentInline, "effect-extent-inline.docx")
+{
+ // The problem was that in case there was inline rotated picture, we
+ // wrote a <wp:effectExtent> full or zeros.
+ if (xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"))
+ {
+ // E.g. this was 0.
+ assertXPath(pXmlDoc, "//wp:effectExtent", "l", "609600");
+ assertXPath(pXmlDoc, "//wp:effectExtent", "r", "590550");
+ assertXPath(pXmlDoc, "//wp:effectExtent", "t", "590550");
+ assertXPath(pXmlDoc, "//wp:effectExtent", "b", "571500");
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testEm, "em.docx")
+{
+ // Test all possible <w:em> arguments.
+ CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::NONE, getProperty<sal_Int16>(getRun(getParagraph(1), 1), "CharEmphasis"));
+ // This was ACCENT_ABOVE.
+ CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 2), "CharEmphasis"));
+ // This was DOT_ABOVE.
+ CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::ACCENT_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 3), "CharEmphasis"));
+ CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::CIRCLE_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 4), "CharEmphasis"));
+ CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_BELOW, getProperty<sal_Int16>(getRun(getParagraph(1), 5), "CharEmphasis"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testFdo77716, "fdo77716.docx")
+{
+ // The problem was that there should be 200 twips spacing between the two paragraphs, but there wasn't any.
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Standard"), uno::UNO_QUERY);
+ // This was 0.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(convertTwipToMm100(200)), getProperty<sal_Int32>(xStyle, "ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testAfterlines, "afterlines.docx")
+{
+ // This was 353, i.e. the value of <w:spacing w:after="200"> from <w:pPrDefault>, instead of <w:spacing w:afterLines="100"/> from <w:pPr>.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(423), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testParagraphMark, "paragraph-mark.docx")
+{
+ // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting.
+
+ // This was 11.
+ CPPUNIT_ASSERT_EQUAL(12.f, getProperty<float>(getParagraph(1), "CharHeight"));
+ // This was empty.
+ CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), getProperty<OUString>(getRun(getParagraph(1), 1), "CharStyleName"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testParagraphMark2, "paragraph-mark2.docx")
+{
+ // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting.
+
+ // This was Segoe UI, set by Char Style FontStyle11 presumably.
+ CPPUNIT_ASSERT_EQUAL(OUString("Arial"), getProperty<OUString>(getRun(getParagraph(1), 1), "CharFontName"));
+ // This was 11, set by Char Style FontStyle11 presumably.
+ CPPUNIT_ASSERT_EQUAL(10.f, getProperty<float>(getRun(getParagraph(1), 1), "CharHeight"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testParagraphMarkNonempty, "paragraph-mark-nonempty.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ if (xmlDocUniquePtr pXmlDoc = parseExport())
+ // There were two <w:sz> elements, make sure the 40 one is dropped and the 20 one is kept.
+ assertXPath(pXmlDoc, "//w:p/w:pPr/w:rPr/w:sz", "val", "20");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testPageBreakBefore, "page-break-before.docx")
+{
+ // This was style::BreakType_PAGE_BEFORE, i.e. page break wasn't ignored, as it should have been.
+ CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTableRtl, "table-rtl.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ // This was text::WritingMode2::LR_TB, i.e. direction of the table was ignored.
+ CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, getProperty<sal_Int16>(xTable, "WritingMode"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist30, "cjklist30.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::TIAN_GAN_ZH, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist31, "cjklist31.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::DI_ZI_ZH, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist34, "cjklist34.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_UPPER_ZH_TW, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist35, "cjklist35.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_LOWER_ZH, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist44, "cjklist44.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_HANGUL_KO, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlTextNumberList, "text_number_list.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_NUMBER, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlTextCardinalList, "text_cardinal_list.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_CARDINAL, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlTextOrdinalList, "text_ordinal_list.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::TEXT_ORDINAL, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testOoxmlSymbolChicagoList, "symbol_chicago_list.docx")
+{
+ sal_Int16 numFormat = getNumberingTypeOfParagraph(1);
+ CPPUNIT_ASSERT_EQUAL(style::NumberingType::SYMBOL_CHICAGO, numFormat);
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testOoxmlNumListZHTW, "numlist-zhtw.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
+
+ assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","taiwaneseCountingThousand" );
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testOoxmlNumListZHCN, "numlist-zhcn.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
+
+ assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","chineseCountingThousand" );
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testOOxmlOutlineNumberTypes, "outline-number-types.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
+
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:pStyle", "val", "Heading1");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt", "val", "none");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[2]/w:numFmt", "val", "decimalEnclosedCircle");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[3]/w:numFmt", "val", "decimal"); // CHARS_GREEK_UPPER_LETTER fallback to decimal
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[4]/w:numFmt", "val", "decimal"); // CHARS_GREEK_LOWER_LETTER fallback to decimal
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[5]/w:numFmt", "val", "arabicAlpha");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[6]/w:numFmt", "val", "hindiVowels");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[7]/w:numFmt", "val", "thaiLetters");
+
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[1]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[2]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[3]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[4]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[5]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[6]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[7]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[2]/w:lvl[8]/w:numFmt", "val", "decimal");
+
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[1]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[2]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[3]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[4]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[5]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[6]/w:numFmt", "val", "decimal");
+ assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[3]/w:lvl[7]/w:numFmt", "val", "decimal");
+
+}
+
+DECLARE_OOXMLEXPORT_TEST(testNumParentStyle, "num-parent-style.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
+ getProperty<sal_Int32>(getParagraph(1), "OutlineLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(getParagraph(1), "ListLabelString"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
+ getProperty<sal_Int32>(getParagraph(2), "OutlineLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(getParagraph(2), "ListLabelString"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
+ getProperty<sal_Int32>(getParagraph(3), "OutlineLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(getParagraph(3), "ListLabelString"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2),
+ getProperty<sal_Int32>(getParagraph(4), "OutlineLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("2.1"), getProperty<OUString>(getParagraph(4), "ListLabelString"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx")
+{
+ uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules");
+ // This was 1, i.e. the numbering on the second level was "1", not "1.1".
+ // Check the paragraph properties, not the list ones, since they can differ due to overrides
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString"));
+
+ // The paragraph marker's red font color was inherited by the number portion, this was ff0000.
+ CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), parseDump("//Special[@nType='PortionType::Number']/SwFont", "color"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testNumOverrideStart, "num-override-start.docx")
+{
+ uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules");
+ // List starts with "1.1"
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["StartWith"].get<sal_Int16>());
+ // But paragraph starts with "1.3"
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ OUString listId;
+ CPPUNIT_ASSERT(xPara->getPropertyValue("ListId") >>= listId);
+ CPPUNIT_ASSERT_EQUAL(OUString("1.3"), getProperty<OUString>(xPara, "ListLabelString"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTextboxRightEdge, "textbox-right-edge.docx")
+{
+ // I'm fairly sure this is not specific to DOCX, but the doc model created
+ // by the ODF import doesn't trigger this bug, so let's test this here
+ // instead of uiwriter.
+ int nShapeLeft = parseDump("//SwAnchoredDrawObject/bounds", "left").toInt32();
+ int nShapeWidth = parseDump("//SwAnchoredDrawObject/bounds", "width").toInt32();
+ int nTextboxLeft = parseDump("//fly/infos/bounds", "left").toInt32();
+ int nTextboxWidth = parseDump("//fly/infos/bounds", "width").toInt32();
+ // This is a rectangle, make sure the right edge of the textbox is still
+ // inside the draw shape.
+ CPPUNIT_ASSERT(nShapeLeft + nShapeWidth >= nTextboxLeft + nTextboxWidth);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testEffectExtentMargin, "effectextent-margin.docx")
+{
+ // This was 318, i.e. oox::drawingml::convertEmuToHmm(114300), effectExtent
+ // wasn't part of the margin, leading to the fly not taking enough space
+ // around itself.
+ CPPUNIT_ASSERT_EQUAL(oox::drawingml::convertEmuToHmm(114300+95250), getProperty<sal_Int32>(getShape(1), "LeftMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf88583, "tdf88583.odt")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(getParagraph(1), "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x00cc00), getProperty<sal_Int32>(getParagraph(1), "FillColor"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf97090, "tdf97090.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0x95B3D7), getProperty<sal_Int32>(xTable->getCellByName("A1"), "BackColor"));
+
+ uno::Reference<container::XEnumerationAccess> paraEnumAccess(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ assert( paraEnumAccess.is() );
+ uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
+
+ assert( paraEnum.is() );
+ uno::Reference<beans::XPropertySet> paragraphProperties(paraEnum->nextElement(), uno::UNO_QUERY);
+ assert( paragraphProperties.is() );
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(paragraphProperties, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), getProperty<sal_Int32>(paragraphProperties, "FillColor"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf89791, "tdf89791.docx")
+{
+ if (mbExported)
+ {
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
+ CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("docProps/custom.xml")));
+ }
+
+ //tdf#102619 - setting FollowStyle with a not-yet-created style was failing. (Titre is created before Corps de texte).
+ uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("Titre"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Corps de texte"), getProperty<OUString>(properties, "FollowStyle"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf91261, "tdf91261.docx")
+{
+ bool snapToGrid = true;
+ uno::Reference< text::XTextRange > xPara = getParagraph( 2 );
+ uno::Reference< beans::XPropertySet > properties( xPara, uno::UNO_QUERY);
+ properties->getPropertyValue("SnapToGrid") >>= snapToGrid ;
+ CPPUNIT_ASSERT_EQUAL(false, snapToGrid);
+
+ uno::Reference< beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
+ sal_Int16 nGridMode;
+ xStyle->getPropertyValue("GridMode") >>= nGridMode;
+ CPPUNIT_ASSERT_EQUAL( sal_Int16(2), nGridMode);
+
+ bool bGridSnapToChars;
+ xStyle->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars;
+ CPPUNIT_ASSERT_EQUAL(true, bGridSnapToChars);
+
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf79639, "tdf79639.docx")
+{
+ // This was 0, floating table in header wasn't converted to a TextFrame.
+ CPPUNIT_ASSERT_EQUAL(1, getShapes());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf89890, "tdf89890.docx")
+{
+ // Numbering picture bullet was too large.
+ uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aProps;
+ xLevels->getByIndex(0) >>= aProps; // 1st level
+
+ bool bFound = false;
+ for (beans::PropertyValue const & rProp : std::as_const(aProps))
+ {
+ if (rProp.Name == "GraphicSize")
+ {
+ // Height of the graphic was too large: 4382 after import, then 2485 after roundtrip.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(279), rProp.Value.get<awt::Size>().Height);
+ bFound = true;
+ }
+ }
+ CPPUNIT_ASSERT(bFound);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf91594, "tdf91594.docx")
+{
+ uno::Reference<text::XTextRange> xPara1(getParagraph(1));
+ CPPUNIT_ASSERT_EQUAL(u'\xf0fb', xPara1->getString()[0] );
+ uno::Reference<text::XTextRange> xPara2(getParagraph(2));
+ CPPUNIT_ASSERT_EQUAL(u'\xf0fc', xPara2->getString()[0] );
+ uno::Reference<text::XTextRange> xPara3(getParagraph(3));
+ CPPUNIT_ASSERT_EQUAL(u'\xf0fd', xPara3->getString()[0] );
+ uno::Reference<text::XTextRange> xPara4(getParagraph(4));
+ CPPUNIT_ASSERT_EQUAL(u'\xf0fe', xPara4->getString()[0] );
+
+ uno::Reference<beans::XPropertySet> xRun(getRun(xPara1,1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontName"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameAsian"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), getProperty<OUString>(xRun, "CharFontNameComplex"));
+}
+DECLARE_OOXMLEXPORT_TEST(testTDF99434, "protectedform.docx")
+{
+ css::uno::Reference<css::lang::XMultiServiceFactory> m_xTextFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference< beans::XPropertySet > xSettings(m_xTextFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ uno::Any aProtect = xSettings->getPropertyValue("ProtectForm");
+ bool bProt = false;
+ aProtect >>= bProt;
+ CPPUNIT_ASSERT(bProt);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf44986, "tdf44986.docx")
+{
+ // Check that the table at the second paragraph.
+ uno::Reference<text::XTextTable> xTable(getParagraphOrTable(2), uno::UNO_QUERY);
+ uno::Reference<table::XTableRows> xTableRows = xTable->getRows();
+ // Check the first row of the table, it should have two cells (one separator).
+ // This was 0: the first row had no separators, so it had only one cell, which was too wide.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators").getLength());
+ // Check content of cells, including the newly added gridAfter cell
+ CPPUNIT_ASSERT_EQUAL(OUString("A1"), uno::Reference<text::XTextRange>(xTable->getCellByName("A1"), uno::UNO_QUERY_THROW)->getString());
+ CPPUNIT_ASSERT_EQUAL(OUString("A2"), uno::Reference<text::XTextRange>(xTable->getCellByName("A2"), uno::UNO_QUERY_THROW)->getString());
+ CPPUNIT_ASSERT_EQUAL(OUString(""), uno::Reference<text::XTextRange>(xTable->getCellByName("B1"), uno::UNO_QUERY_THROW)->getString());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf118682, "tdf118682.fodt")
+{
+ // Support cell references in table formulas
+ xmlDocUniquePtr pXmlDoc = parseExport();
+
+ // Formula fields were completely missing.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r/w:fldChar", 3);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3);
+
+ // Cell references were parenthesized: <A1>+<A2> and SUM(<A1:A3>)
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", " = A1+A2");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", " = SUM(A1:A3)");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf133163, "tdf133163.fodt")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+
+ // Formula cells were completely missing.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r/w:fldChar", 3);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r/w:fldChar", 3);
+
+ // Cell references were parenthesized: <A1>+<A2> and SUM(<A1:A3>)
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:instrText", " = A1+A2");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:instrText", " = SUM(A1:A3)");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf133647, "tdf133647.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+ if (!pXmlDoc)
+ return;
+
+ // Keep original formula during round-trip
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(A1,B1)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(C1:D1)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " = SUM(A1,5,B1:C1,6)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " = (1+2)*SUM(C1,D1)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " = 3*(2+SUM(A1:C1)+7)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " = 1+(SUM(1,2))");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " = (SUM(C1,5)*(2+7))*(3+SUM(1,B1))");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " = sum(a1,b1)");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf123386, "tdf123386.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+ if (!pXmlDoc)
+ return;
+
+ // Keep original formula during round-trip
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " = A1 < 2");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = B1 > 1");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc[4]/w:p/w:r[2]/w:instrText", " = C1=3");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc[4]/w:p/w:r[2]/w:instrText", " = D1 <> 3");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND(A1=1,B1=2)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND((A1<1),(B1<>2))");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc[4]/w:p/w:r[2]/w:instrText", " = OR(A1=1,B1=2)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[10]/w:tc[4]/w:p/w:r[2]/w:instrText", " = OR(TRUE,FALSE)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[11]/w:tc[4]/w:p/w:r[2]/w:instrText", " = NOT(TRUE)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[12]/w:tc[4]/w:p/w:r[2]/w:instrText", " = AND(1,DEFINED(ABC1))");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf123389, "tdf123389.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseExport();
+ if (!pXmlDoc)
+ return;
+
+ // Keep original formula during round-trip
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[4]/w:p/w:r[2]/w:instrText", " = ROUND(2.345,1)");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[4]/w:p/w:r[2]/w:instrText", " = ROUND(A1,2)");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf106953, "tdf106953.docx")
+{
+ uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules");
+ // This was -635, so the tab of the numbering expanded to a small value instead of matching Word's larger value.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), comphelper::SequenceAsHashMap(xRules->getByIndex(0))["FirstLineIndent"].get<sal_Int32>());
+}
+
+DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf115094v3, "tdf115094v3.docx")
+{
+ // floating table is now exported directly without surrounding frame
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpX", "1996");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblpPr", "tblpY", "1064");
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */