LCOV - code coverage report
Current view: top level - sw/qa/extras/inc - swmodeltestbase.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 362 382 94.8 %
Date: 2014-11-03 Functions: 102 105 97.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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             :  */
       9             : 
      10             : #ifndef INCLUDED_SW_QA_EXTRAS_INC_SWMODELTESTBASE_HXX
      11             : #define INCLUDED_SW_QA_EXTRAS_INC_SWMODELTESTBASE_HXX
      12             : 
      13             : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
      14             : #include <com/sun/star/frame/Desktop.hpp>
      15             : #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
      16             : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
      17             : #include <com/sun/star/style/XAutoStylesSupplier.hpp>
      18             : #include <com/sun/star/style/XAutoStyleFamily.hpp>
      19             : #include <com/sun/star/text/XPageCursor.hpp>
      20             : #include <com/sun/star/text/XTextDocument.hpp>
      21             : #include <com/sun/star/text/XTextRange.hpp>
      22             : #include <com/sun/star/text/XTextTable.hpp>
      23             : #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
      24             : #include <com/sun/star/table/XCell.hpp>
      25             : #include <com/sun/star/table/BorderLine2.hpp>
      26             : #include <com/sun/star/task/XJob.hpp>
      27             : #include <com/sun/star/sdb/CommandType.hpp>
      28             : #include <com/sun/star/sdb/DatabaseContext.hpp>
      29             : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
      30             : #include <com/sun/star/text/MailMergeType.hpp>
      31             : 
      32             : #include <test/bootstrapfixture.hxx>
      33             : #include <test/xmltesttools.hxx>
      34             : #include <unotest/macros_test.hxx>
      35             : #include <unotools/ucbstreamhelper.hxx>
      36             : #include <rtl/strbuf.hxx>
      37             : #include <rtl/ustrbuf.hxx>
      38             : #include <rtl/byteseq.hxx>
      39             : #include <comphelper/processfactory.hxx>
      40             : #include <unotools/tempfile.hxx>
      41             : #include <unotools/localfilehelper.hxx>
      42             : #include <unotools/mediadescriptor.hxx>
      43             : #include <dbmgr.hxx>
      44             : #include <unoprnms.hxx>
      45             : 
      46             : #include <unotxdoc.hxx>
      47             : #include <docsh.hxx>
      48             : #include <doc.hxx>
      49             : #include <IDocumentLayoutAccess.hxx>
      50             : #include <rootfrm.hxx>
      51             : 
      52             : using namespace css;
      53             : 
      54             : #define DEFAULT_STYLE "Default Style"
      55             : #define EMU_TO_MM100(EMU) (EMU / 360)
      56             : 
      57             : /**
      58             :  * Macro to declare a new test (with full round-trip. To test
      59             :  * import only use the DECLARE_SW_IMPORT_TEST macro instead).
      60             :  * In order to add a new test, one only needs to use this macro
      61             :  * and then specify the test content, like this:
      62             :  *
      63             :  * DECLARE_SW_ROUNDTRIP_TEST(MyTest, "myfilename.docx", Test)
      64             :  * {
      65             :  *      CPPUNIT_ASSERT_EQUAL(blabla);
      66             :  * }
      67             :  *
      68             :  */
      69             : #define DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, BaseClass) \
      70             :     class TestName : public BaseClass { \
      71             :         protected:\
      72             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString::createFromAscii(#TestName); } \
      73             :         public:\
      74             :     CPPUNIT_TEST_SUITE(TestName); \
      75             :     CPPUNIT_TEST(Import); \
      76             :     CPPUNIT_TEST(Import_Export_Import); \
      77             :     CPPUNIT_TEST_SUITE_END(); \
      78             :     \
      79             :     void Import() { \
      80             :         executeImportTest(filename);\
      81             :     }\
      82             :     void Import_Export_Import() {\
      83             :         executeImportExportImportTest(filename);\
      84             :     }\
      85             :     void verify() SAL_OVERRIDE;\
      86             :     }; \
      87             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
      88             :     void TestName::verify()
      89             : 
      90             : #if 1
      91             : #define DECLARE_OOXMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      92             : #define DECLARE_OOXMLEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      93             : #define DECLARE_RTFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      94             : #define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      95             : #define DECLARE_ODFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      96             : 
      97             : // For testing during development of a test, you want to use
      98             : // DECLARE_OOXMLEXPORT_TEST_ONLY, and change the above to #if 0
      99             : // Of course, don't forget to set back to #if 1 when you are done :-)
     100             : #else
     101             : #define DECLARE_OOXMLIMPORT_TEST_ONLY(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
     102             : #define DECLARE_OOXMLEXPORT_TEST_ONLY(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
     103             : #define DECLARE_RTFIMPORT_TEST_ONLY(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
     104             : #define DECLARE_RTFEXPORT_TEST_ONLY(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
     105             : #define DECLARE_ODFIMPORT_TEST_ONLY(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
     106             : 
     107             : #undef DECLARE_OOXMLEXPORT_TEST
     108             : #define DECLARE_OOXMLIMPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
     109             : #define DECLARE_OOXMLEXPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
     110             : #define DECLARE_RTFIMPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
     111             : #define DECLARE_RTFEXPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
     112             : #define DECLARE_ODFIMPORT_TEST(TestName, filename) class disabled##TestName : public Test { void disabled(); }; void disabled##TestName::disabled()
     113             : #endif
     114             : 
     115             : #define DECLARE_SW_IMPORT_TEST(TestName, filename, BaseClass) \
     116             :     class TestName : public BaseClass { \
     117             :         protected:\
     118             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString::createFromAscii(#TestName); } \
     119             :         public:\
     120             :     CPPUNIT_TEST_SUITE(TestName); \
     121             :     CPPUNIT_TEST(Import); \
     122             :     CPPUNIT_TEST_SUITE_END(); \
     123             :     \
     124             :     void Import() { \
     125             :         executeImportTest(filename);\
     126             :     }\
     127             :     void verify() SAL_OVERRIDE;\
     128             :     }; \
     129             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
     130             :     void TestName::verify()
     131             : 
     132             : #define DECLARE_SW_EXPORT_TEST(TestName, filename, BaseClass) \
     133             :     class TestName : public BaseClass { \
     134             :         protected:\
     135             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString::createFromAscii(#TestName); } \
     136             :         public:\
     137             :     CPPUNIT_TEST_SUITE(TestName); \
     138             :     CPPUNIT_TEST(Import_Export); \
     139             :     CPPUNIT_TEST_SUITE_END(); \
     140             :     \
     141             :     void Import_Export() {\
     142             :         executeImportExport(filename);\
     143             :     }\
     144             :     void verify() SAL_OVERRIDE;\
     145             :     }; \
     146             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
     147             :     void TestName::verify()
     148             : 
     149             : #define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, BaseClass) \
     150             :     class TestName : public BaseClass { \
     151             :     protected: \
     152             :         virtual OUString getTestName() SAL_OVERRIDE { return OUString::createFromAscii(#TestName); } \
     153             :     public: \
     154             :         CPPUNIT_TEST_SUITE(TestName); \
     155             :         CPPUNIT_TEST(MailMerge); \
     156             :         CPPUNIT_TEST_SUITE_END(); \
     157             :     \
     158             :         void MailMerge() { \
     159             :             executeMailMergeTest(filename, datasource, tablename); \
     160             :         } \
     161             :         void verify() SAL_OVERRIDE; \
     162             :     }; \
     163             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
     164             :     void TestName::verify()
     165             : 
     166             : /**
     167             :  * Maps database URIs to the registered database names for quick lookups
     168             :  */
     169             : typedef std::map<OUString, OUString> DBuriMap;
     170          38 : DBuriMap aDBuriMap;
     171             : 
     172             : /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
     173             : class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
     174             : {
     175             : private:
     176             :     OUString maFilterOptions;
     177             : 
     178             : protected:
     179             :     uno::Reference< lang::XComponent > mxComponent;
     180             :     uno::Reference< lang::XComponent > mxMMComponent;
     181             :     uno::Reference< com::sun::star::task::XJob > mxJob;
     182             :     uno::Sequence< beans::NamedValue > mSeqMailMergeArgs;
     183             : 
     184             :     xmlBufferPtr mpXmlBuffer;
     185             :     const char* mpTestDocumentPath;
     186             :     const char* mpFilter;
     187             : 
     188             :     template<typename T>
     189             :     struct MethodEntry
     190             :     {
     191             :         const char* pName;
     192             :         void (T::*pMethod)();
     193             :     };
     194             : 
     195             :     sal_uInt32 mnStartTime;
     196             :     utl::TempFile maTempFile;
     197             :     bool mbExported; ///< Does maTempFile already contain something useful?
     198             :     sal_Int16 nCurOutputType;
     199             : 
     200             : protected:
     201           0 :     virtual OUString getTestName() { return OUString(); }
     202             : 
     203             : public:
     204             :     OUString& getFilterOptions()
     205             :     {
     206             :         return maFilterOptions;
     207             :     }
     208          22 :     void setFilterOptions(const OUString &rFilterOptions)
     209             :     {
     210          22 :         maFilterOptions = rFilterOptions;
     211          22 :     }
     212             : 
     213        2800 :     SwModelTestBase(const char* pTestDocumentPath = "", const char* pFilter = "")
     214             :         : mpXmlBuffer(0)
     215             :         , mpTestDocumentPath(pTestDocumentPath)
     216             :         , mpFilter(pFilter)
     217             :         , mnStartTime(0)
     218             :         , mbExported(false)
     219        2800 :         , nCurOutputType(0)
     220             :     {
     221        2800 :         maTempFile.EnableKillingFile();
     222        2800 :     }
     223             : 
     224        2800 :     virtual ~SwModelTestBase()
     225        2800 :     {}
     226             : 
     227        2800 :     virtual void setUp() SAL_OVERRIDE
     228             :     {
     229        2800 :         test::BootstrapFixture::setUp();
     230             : 
     231        2800 :         mxDesktop.set(css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
     232        2800 :     }
     233             : 
     234        2800 :     virtual void tearDown() SAL_OVERRIDE
     235             :     {
     236        2800 :         if (mxComponent.is())
     237        2686 :             mxComponent->dispose();
     238        2800 :         if (mxMMComponent.is())
     239             :         {
     240           4 :             if (nCurOutputType == text::MailMergeType::SHELL)
     241             :             {
     242           4 :                 SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument*>(mxMMComponent.get());
     243           4 :                 CPPUNIT_ASSERT(pTxtDoc);
     244           4 :                 pTxtDoc->GetDocShell()->DoClose();
     245             :             }
     246             :             else
     247           0 :                 mxMMComponent->dispose();
     248             :         }
     249             : 
     250        2800 :         test::BootstrapFixture::tearDown();
     251        2800 :     }
     252             : 
     253             : protected:
     254             :     /**
     255             :      * Helper func used by each unit test to test the 'import' code.
     256             :      * (Loads the requested file and then calls 'verify' method)
     257             :      */
     258        1760 :     void executeImportTest(const char* filename)
     259             :     {
     260             :         // If the testcase is stored in some other format, it's pointless to test.
     261        1760 :         if (mustTestImportOf(filename))
     262             :         {
     263        1646 :             maTempFile.EnableKillingFile(false);
     264        1646 :             header();
     265        1646 :             preTest(filename);
     266        1646 :             load(mpTestDocumentPath, filename);
     267        1646 :             postTest(filename);
     268        1646 :             verify();
     269        1646 :             finish();
     270        1646 :             maTempFile.EnableKillingFile();
     271             :         }
     272        1760 :     }
     273             : 
     274             :     /**
     275             :      * Helper func used by each unit test to test the 'export' code.
     276             :      * (Loads the requested file, save it to temp file, load the
     277             :      * temp file and then calls 'verify' method)
     278             :      */
     279         984 :     void executeImportExportImportTest(const char* filename)
     280             :     {
     281         984 :         maTempFile.EnableKillingFile(false);
     282         984 :         header();
     283         984 :         preTest(filename);
     284         984 :         load(mpTestDocumentPath, filename);
     285         984 :         reload(mpFilter, filename);
     286         984 :         postTest(filename);
     287         984 :         verify();
     288         984 :         finish();
     289         984 :         maTempFile.EnableKillingFile();
     290         984 :     }
     291             : 
     292             :     /**
     293             :      * Helper func used by each unit test to test the 'export' code.
     294             :      * (Loads the requested file for document base (this represents
     295             :      * the initial document condition), exports with the desired
     296             :      * export filter and then calls 'verify' method)
     297             :      */
     298          12 :     void executeImportExport(const char* filename)
     299             :     {
     300          12 :         maTempFile.EnableKillingFile(false);
     301          12 :         header();
     302          12 :         preTest(filename);
     303          12 :         load(mpTestDocumentPath, filename);
     304          12 :         save(OUString::createFromAscii(mpFilter), maTempFile);
     305          12 :         maTempFile.EnableKillingFile(false);
     306          12 :         postTest(filename);
     307          12 :         verify();
     308          12 :         finish();
     309          12 :         maTempFile.EnableKillingFile();
     310          12 :     }
     311             : 
     312             :     /**
     313             :      * Helper func used by each unit test to test the 'mail merge' code.
     314             :      *
     315             :      * Registers the data source, loads the original file as reference,
     316             :      * initializes the mail merge job and its default argument sequence.
     317             :      *
     318             :      * The 'verify' method actually has to execute the mail merge by
     319             :      * calling executeMailMerge() after modifying the job arguments.
     320             :      */
     321           4 :     void executeMailMergeTest(const char* filename, const char* datasource, const char* tablename = 0)
     322             :     {
     323           4 :         header();
     324           4 :         preTest(filename);
     325           4 :         load(mpTestDocumentPath, filename);
     326             : 
     327           4 :         const OUString aPrefix( "LOMM_" );
     328           8 :         utl::TempFile aTempDir(nullptr, true);
     329           8 :         const OUString aWorkDir = aTempDir.GetURL();
     330           8 :         const OUString aURI( getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(datasource) );
     331           8 :         OUString aDBName = registerDBsource( aURI, aPrefix, aWorkDir );
     332           4 :         initMailMergeJobAndArgs( filename, tablename, aDBName, aPrefix, aWorkDir );
     333             : 
     334           4 :         postTest(filename);
     335           4 :         verify();
     336           4 :         finish();
     337             : 
     338           8 :         ::utl::removeTree(aWorkDir);
     339           4 :     }
     340             : 
     341             :     /**
     342             :      * Function overloaded by unit test. See DECLARE_SW_*_TEST macros
     343             :      */
     344           0 :     virtual void verify()
     345             :     {
     346           0 :         CPPUNIT_FAIL( "verify method must be overridden" );
     347           0 :     }
     348             : 
     349             :     /**
     350             :      * Override this function if interested in skipping import test for this file
     351             :      */
     352         776 :      virtual bool mustTestImportOf(const char* /* filename */) const
     353             :      {
     354         776 :         return true;
     355             :      }
     356             :     /**
     357             :      * Override this function if some special filename-specific setup is needed
     358             :      */
     359        1954 :     virtual void preTest(const char* /*filename*/)
     360             :     {
     361        1954 :     }
     362             : 
     363             :     /**
     364             :      * Override this function if some special filename-specific teardown is needed
     365             :      */
     366        1954 :     virtual void postTest(const char* /*filename*/)
     367             :     {
     368        1954 :     }
     369             : 
     370             :     /**
     371             :      * Override this function if calcing layout is not needed
     372             :      */
     373        3642 :     virtual bool mustCalcLayoutOf(const char* /*filename*/)
     374             :     {
     375        3642 :         return true;
     376             :     }
     377             : 
     378             :     /**
     379             :      * Override this function if validation is wanted
     380             :      */
     381         852 :     virtual bool mustValidate(const char* /*filename*/) const
     382             :     {
     383         852 :         return false;
     384             :     }
     385             : 
     386             : private:
     387          66 :     void dumpLayout()
     388             :     {
     389             :         // create the xml writer
     390          66 :         mpXmlBuffer = xmlBufferCreate();
     391          66 :         xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(mpXmlBuffer, 0);
     392          66 :         xmlTextWriterStartDocument(pXmlWriter, NULL, NULL, NULL);
     393             : 
     394             :         // create the dump
     395          66 :         SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
     396          66 :         CPPUNIT_ASSERT(pTxtDoc);
     397          66 :         SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
     398          66 :         SwRootFrm* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     399          66 :         pLayout->dumpAsXml(pXmlWriter);
     400             : 
     401             :         // delete xml writer
     402          66 :         xmlTextWriterEndDocument(pXmlWriter);
     403          66 :         xmlFreeTextWriter(pXmlWriter);
     404          66 :     }
     405             : 
     406        3666 :     void calcLayout()
     407             :     {
     408        3666 :         SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
     409        3666 :         CPPUNIT_ASSERT(pTxtDoc);
     410        3666 :         SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
     411        3666 :         pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
     412        3666 :     }
     413             : 
     414             : protected:
     415             :     /// Get the length of the whole document.
     416          22 :     int getLength()
     417             :     {
     418          22 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     419          44 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     420          44 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     421          44 :         OUStringBuffer aBuf;
     422          68 :         while (xParaEnum->hasMoreElements())
     423             :         {
     424          24 :             uno::Reference<container::XEnumerationAccess> xRangeEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
     425          48 :             uno::Reference<container::XEnumeration> xRangeEnum = xRangeEnumAccess->createEnumeration();
     426          80 :             while (xRangeEnum->hasMoreElements())
     427             :             {
     428          32 :                 uno::Reference<text::XTextRange> xRange(xRangeEnum->nextElement(), uno::UNO_QUERY);
     429          32 :                 aBuf.append(xRange->getString());
     430          32 :             }
     431          24 :         }
     432          44 :         return aBuf.getLength();
     433             :     }
     434             : 
     435             :     /// Get a family of styles, see com.sun.star.style.StyleFamilies for possible values.
     436         214 :     uno::Reference<container::XNameAccess> getStyles(const OUString& aFamily)
     437             :     {
     438         214 :         uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
     439         428 :         uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     440         214 :         uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(aFamily), uno::UNO_QUERY);
     441         428 :         return xStyleFamily;
     442             :     }
     443             : 
     444             :     /// Get a family of auto styles, see com.sun.star.style.StyleFamilies for possible values.
     445           4 :     uno::Reference<style::XAutoStyleFamily> getAutoStyles(const OUString& aFamily)
     446             :     {
     447           4 :         uno::Reference< style::XAutoStylesSupplier > xAutoStylesSupplier(mxComponent, uno::UNO_QUERY);
     448           8 :         uno::Reference< style::XAutoStyles > xAutoStyles(xAutoStylesSupplier->getAutoStyles());
     449           4 :         uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(xAutoStyles->getByName(aFamily), uno::UNO_QUERY);
     450           8 :         return xAutoStyleFamily;
     451             :     }
     452             : 
     453             :     /**
     454             :      * Extract a value from the layout dump using an XPath expression and an attribute name.
     455             :      *
     456             :      * If the attribute is omitted, the text of the node is returned.
     457             :      */
     458         242 :     OUString parseDump(const OString& aXPath, const OString& aAttribute = OString())
     459             :     {
     460         242 :         if (!mpXmlBuffer)
     461          66 :             dumpLayout();
     462             : 
     463         242 :         xmlDocPtr pXmlDoc = xmlParseMemory((const char*)xmlBufferContent(mpXmlBuffer), xmlBufferLength(mpXmlBuffer));;
     464             : 
     465         242 :         xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
     466         242 :         xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(aXPath.getStr()), pXmlXpathCtx);
     467         242 :         xmlNodeSetPtr pXmlNodes = pXmlXpathObj->nodesetval;
     468         242 :         CPPUNIT_ASSERT_EQUAL_MESSAGE("parsing dump failed", 1, xmlXPathNodeSetGetLength(pXmlNodes));
     469         242 :         xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
     470         242 :         OUString aRet;
     471         242 :         if (aAttribute.getLength())
     472          52 :             aRet = OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(aAttribute.getStr())));
     473             :         else
     474         190 :             aRet = OUString::createFromAscii((const char*)XML_GET_CONTENT(pXmlNode));
     475             : 
     476         242 :         xmlFreeDoc(pXmlDoc);
     477             : 
     478         242 :         return aRet;
     479             :     }
     480             : 
     481             :     template< typename T >
     482         186 :     T getProperty( const uno::Any& obj, const OUString& name ) const
     483             :     {
     484         186 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY_THROW );
     485         186 :         T data = T();
     486         186 :         if (!(properties->getPropertyValue(name) >>= data))
     487             :         {
     488           0 :             CPPUNIT_FAIL("the property is of unexpected type or void");
     489             :         }
     490         186 :         return data;
     491             :     }
     492             : 
     493             :     template< typename T >
     494        2824 :     T getProperty( const uno::Reference< uno::XInterface >& obj, const OUString& name ) const
     495             :     {
     496        2824 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY_THROW );
     497        2824 :         T data = T();
     498        2824 :         if (!(properties->getPropertyValue(name) >>= data))
     499             :         {
     500           0 :             CPPUNIT_FAIL("the property is of unexpected type or void");
     501             :         }
     502        2824 :         return data;
     503             :     }
     504             : 
     505          36 :     bool hasProperty(const uno::Reference<uno::XInterface>& obj, const OUString& name) const
     506             :     {
     507          36 :         uno::Reference<beans::XPropertySet> properties(obj, uno::UNO_QUERY_THROW);
     508          36 :         return properties->getPropertySetInfo()->hasPropertyByName(name);
     509             :     }
     510             : 
     511             :     /// Get number of paragraphs of the document.
     512           4 :     int getParagraphs()
     513             :     {
     514           4 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     515           8 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     516           8 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     517           4 :         int nRet = 0;
     518          14 :         while (xParaEnum->hasMoreElements())
     519             :         {
     520           6 :             xParaEnum->nextElement();
     521           6 :             nRet++;
     522             :         }
     523           8 :         return nRet;
     524             :     }
     525             : 
     526        1100 :     uno::Reference<text::XTextContent> getParagraphOrTable(int number, uno::Reference<text::XText> xText = uno::Reference<text::XText>()) const
     527             :     {
     528        1100 :         uno::Reference<container::XEnumerationAccess> paraEnumAccess;
     529        1100 :         if (xText.is())
     530         170 :             paraEnumAccess.set(xText, uno::UNO_QUERY);
     531             :         else
     532             :         {
     533         930 :             uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
     534         930 :             paraEnumAccess.set(textDocument->getText(), uno::UNO_QUERY);
     535             :         }
     536        2200 :         uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
     537        2718 :         for( int i = 1;
     538             :              i < number;
     539             :              ++i )
     540        1618 :             paraEnum->nextElement();
     541        1100 :         uno::Reference< text::XTextContent> const xElem(paraEnum->nextElement(),
     542        1100 :                 uno::UNO_QUERY_THROW);
     543        2198 :         return xElem;
     544             :     }
     545             : 
     546             :     // Get paragraph (counted from 1), optionally check it contains the given text.
     547         910 :     uno::Reference< text::XTextRange > getParagraph( int number, const OUString& content = OUString() ) const
     548             :     {
     549             :         uno::Reference<text::XTextRange> const xParagraph(
     550         910 :                 getParagraphOrTable(number), uno::UNO_QUERY_THROW);
     551         908 :         if( !content.isEmpty())
     552         100 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "paragraph does not have expected content", content, xParagraph->getString());
     553         908 :         return xParagraph;
     554             :     }
     555             : 
     556         154 :     uno::Reference<text::XTextRange> getParagraphOfText(int number, uno::Reference<text::XText> xText, const OUString& content = OUString()) const
     557             :     {
     558         154 :         uno::Reference<text::XTextRange> const xParagraph(getParagraphOrTable(number, xText), uno::UNO_QUERY_THROW);
     559         154 :         if (!content.isEmpty())
     560          20 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "paragraph does not contain expected content", content, xParagraph->getString());
     561         154 :         return xParagraph;
     562             :     }
     563             : 
     564             :     /// Get run (counted from 1) of a paragraph, optionally check it contains the given text.
     565         824 :     uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, const OUString& content = OUString()) const
     566             :     {
     567         824 :         uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY);
     568        1648 :         uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     569        1820 :         for (int i = 1; i < number; ++i)
     570         996 :             xRunEnum->nextElement();
     571         824 :         uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
     572         824 :         if( !content.isEmpty())
     573          78 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "run does not contain expected content", content, xRun->getString());
     574        1648 :         return xRun;
     575             :     }
     576             : 
     577             :     /// Get math formula string of a run.
     578         228 :     OUString getFormula(uno::Reference<text::XTextRange> xRun) const
     579             :     {
     580         228 :         uno::Reference<container::XContentEnumerationAccess> xContentEnumAccess(xRun, uno::UNO_QUERY);
     581         456 :         uno::Reference<container::XEnumeration> xContentEnum(xContentEnumAccess->createContentEnumeration(""), uno::UNO_QUERY);
     582         456 :         uno::Reference<beans::XPropertySet> xFormula(xContentEnum->nextElement(), uno::UNO_QUERY);
     583         456 :         return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
     584             :     }
     585             : 
     586             :     /// get cell of a table; table can be retrieved with getParagraphOrTable
     587          14 :     uno::Reference<table::XCell> getCell(
     588             :             uno::Reference<uno::XInterface> const& xTableIfc,
     589             :             OUString const& rCell, OUString const& rContent = OUString())
     590             :     {
     591             :         uno::Reference<text::XTextTable> const xTable(xTableIfc,
     592          14 :                 uno::UNO_QUERY_THROW);
     593             :         uno::Reference<table::XCell> const xCell(
     594          14 :                 xTable->getCellByName(rCell), uno::UNO_SET_THROW);
     595          14 :         if (!rContent.isEmpty())
     596             :         {
     597             :             uno::Reference<text::XText> const xCellText(xCell,
     598           6 :                     uno::UNO_QUERY_THROW);
     599           6 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("cell does not contain expected content", rContent, xCellText->getString());
     600             :         }
     601          14 :         return xCell;
     602             :     }
     603             : 
     604             :     /// Get shape (counted from 1)
     605         632 :     uno::Reference<drawing::XShape> getShape(int number)
     606             :     {
     607         632 :         uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     608        1264 :         uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
     609         632 :         uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(number - 1), uno::UNO_QUERY);
     610        1258 :         return xShape;
     611             :     }
     612             : 
     613             :     /// Get shape by name
     614          12 :     uno::Reference<drawing::XShape> getShapeByName(const OUString& aName)
     615             :     {
     616          12 :         uno::Reference<drawing::XShape> xRet;
     617             : 
     618          24 :         uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     619          24 :         uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
     620          24 :         for (sal_Int32 i = 0; i < xDrawPage->getCount(); ++i)
     621             :         {
     622          24 :             uno::Reference<container::XNamed> xShape(xDrawPage->getByIndex(i), uno::UNO_QUERY);
     623          24 :             if (xShape->getName() == aName)
     624             :             {
     625          12 :                 xRet.set(xShape, uno::UNO_QUERY);
     626          12 :                 break;
     627             :             }
     628          12 :         }
     629             : 
     630          24 :         return xRet;
     631             :     }
     632             :     /// Get TextFrame by name
     633          12 :     uno::Reference<drawing::XShape> getTextFrameByName(const OUString& aName)
     634             :     {
     635          12 :         uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
     636          24 :         uno::Reference<container::XNameAccess> xNameAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
     637          12 :         uno::Reference<drawing::XShape> xShape(xNameAccess->getByName(aName), uno::UNO_QUERY);
     638          24 :         return xShape;
     639             :     }
     640             : 
     641        2646 :     void header()
     642             :     {
     643        2646 :         std::cout << "File tested,Execution Time (ms)" << std::endl;
     644        2646 :     }
     645             : 
     646        2686 :     void load(const char* pDir, const char* pName)
     647             :     {
     648        2686 :         if (mxComponent.is())
     649           0 :             mxComponent->dispose();
     650             :         // Output name early, so in the case of a hang, the name of the hanging input file is visible.
     651        2686 :         std::cout << pName << ",";
     652        2686 :         mnStartTime = osl_getGlobalTimer();
     653        2686 :         mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName), "com.sun.star.text.TextDocument");
     654        2686 :         if (mustCalcLayoutOf(pName))
     655        2684 :             calcLayout();
     656        2686 :     }
     657             : 
     658         984 :     void reload(const char* pFilter, const char* filename)
     659             :     {
     660         984 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     661        1968 :         OUString aFilterName = OUString::createFromAscii(pFilter);
     662        1968 :         utl::MediaDescriptor aMediaDescriptor;
     663         984 :         aMediaDescriptor["FilterName"] <<= aFilterName;
     664         984 :         if (!maFilterOptions.isEmpty())
     665           0 :             aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
     666         984 :         xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
     667        1968 :         uno::Reference<lang::XComponent> xComponent(xStorable, uno::UNO_QUERY);
     668         984 :         xComponent->dispose();
     669         984 :         mbExported = true;
     670         984 :         mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument");
     671         984 :         if (mustValidate(filename))
     672             :         {
     673          10 :             if(aFilterName == "Office Open XML Text")
     674             :             {
     675             :                 // too many validation errors right now
     676          10 :                 validate(maTempFile.GetFileName(), test::OOXML);
     677             :             }
     678           0 :             else if(aFilterName == "writer8")
     679             :             {
     680             :                 // still a few validation errors
     681           0 :                 validate(maTempFile.GetFileName(), test::ODF);
     682             :             }
     683             :         }
     684             : 
     685         984 :         if (mpXmlBuffer)
     686             :         {
     687           0 :             xmlBufferFree(mpXmlBuffer);
     688           0 :             mpXmlBuffer = 0;
     689             :         }
     690         984 :         if (mustCalcLayoutOf(filename))
     691        1966 :             calcLayout();
     692         984 :     }
     693             : 
     694             :     /// Save the loaded document to a tempfile. Can be used to check the resulting docx/odt directly as a ZIP file.
     695          14 :     void save(const OUString& aFilterName, utl::TempFile& rTempFile)
     696             :     {
     697          14 :         rTempFile.EnableKillingFile();
     698          14 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     699          28 :         utl::MediaDescriptor aMediaDescriptor;
     700          14 :         aMediaDescriptor["FilterName"] <<= aFilterName;
     701          14 :         if (!maFilterOptions.isEmpty())
     702           6 :             aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
     703          28 :         xStorable->storeToURL(rTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
     704          14 :     }
     705             : 
     706        2646 :     void finish()
     707             :     {
     708        2646 :         sal_uInt32 nEndTime = osl_getGlobalTimer();
     709        2646 :         std::cout << (nEndTime - mnStartTime) << std::endl;
     710        2646 :         if (mpXmlBuffer)
     711             :         {
     712          66 :             xmlBufferFree(mpXmlBuffer);
     713          66 :             mpXmlBuffer = 0;
     714             :         }
     715        2646 :     }
     716             : 
     717             :     /// Get page count.
     718          32 :     int getPages()
     719             :     {
     720          32 :         uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     721          64 :         uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
     722          64 :         uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
     723          32 :         xCursor->jumpToLastPage();
     724          64 :         return xCursor->getPage();
     725             :     }
     726             : 
     727             :     /**
     728             :      * Given that some problem doesn't affect the result in the importer, we
     729             :      * test the resulting file directly, by opening the zip file, parsing an
     730             :      * xml stream, and asserting an XPath expression. This method returns the
     731             :      * xml stream, so that you can do the asserting.
     732             :      */
     733        1068 :     xmlDocPtr parseExport(const OUString& rStreamName = OUString("word/document.xml"))
     734             :     {
     735        1068 :         if (!mbExported)
     736         518 :             return 0;
     737             : 
     738             :         // Read the XML stream we're interested in.
     739         550 :         uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
     740        1100 :         uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(rStreamName), uno::UNO_QUERY);
     741        1100 :         boost::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
     742             : 
     743         550 :         xmlDocPtr pXmlDoc = parseXmlStream(pStream.get());
     744         550 :         pXmlDoc->name = reinterpret_cast<char *>(xmlStrdup(reinterpret_cast<xmlChar const *>(OUStringToOString(maTempFile.GetURL(), RTL_TEXTENCODING_UTF8).getStr())));
     745        1100 :         return pXmlDoc;
     746             :     }
     747             : 
     748             :     /**
     749             :      * Helper method to return nodes represented by rXPath.
     750             :      */
     751        2230 :     virtual void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) SAL_OVERRIDE
     752             :     {
     753        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main"));
     754        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml"));
     755        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006"));
     756        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape"));
     757        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"));
     758        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"));
     759        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wp14"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"));
     760        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main"));
     761        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("pic"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/picture"));
     762        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rels"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships"));
     763        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w14"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordml"));
     764        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("m"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/math"));
     765        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types"));
     766        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("lc"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"));
     767        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("extended-properties"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"));
     768        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"), BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main"));
     769        2230 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("o"), BAD_CAST("urn:schemas-microsoft-com:office:office"));
     770        2230 :     }
     771             : 
     772           4 :     virtual OUString registerDBsource( const OUString &aURI, const OUString &aPrefix, const OUString &aWorkDir )
     773             :     {
     774           4 :         OUString aDBName;
     775           4 :         DBuriMap::const_iterator pos = aDBuriMap.find( aURI );
     776           4 :         if (pos == aDBuriMap.end())
     777             :         {
     778           4 :             aDBName = SwDBManager::LoadAndRegisterDataSource( aURI, &aPrefix, &aWorkDir );
     779           4 :             aDBuriMap.insert( std::pair< OUString, OUString >( aURI, aDBName ) );
     780           4 :             std::cout << "New datasource name: '" << aDBName << "'" << std::endl;
     781             :         }
     782             :         else
     783             :         {
     784           0 :             aDBName = pos->second;
     785           0 :             std::cout << "Old datasource name: '" << aDBName << "'" << std::endl;
     786             :         }
     787           4 :         CPPUNIT_ASSERT(!aDBName.isEmpty());
     788           4 :         return aDBName;
     789             :     }
     790             : 
     791           4 :     virtual void initMailMergeJobAndArgs( const char* filename, const char* tablename, const OUString &aDBName,
     792             :                                           const OUString &aPrefix, const OUString &aWorkDir )
     793             :     {
     794           4 :         uno::Reference< task::XJob > xJob( getMultiServiceFactory()->createInstance( "com.sun.star.text.MailMerge" ), uno::UNO_QUERY_THROW );
     795           4 :         mxJob.set( xJob );
     796             : 
     797           4 :         int seq_id = 5;
     798           4 :         if (tablename) seq_id += 2;
     799           4 :         mSeqMailMergeArgs.realloc( seq_id );
     800             : 
     801           4 :         seq_id = 0;
     802           4 :         mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_TYPE ), uno::Any( text::MailMergeType::SHELL ) );
     803           8 :         mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DOCUMENT_URL ), uno::Any(
     804          12 :                                         ( OUString(getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(filename)) ) ) );
     805           4 :         mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DATA_SOURCE_NAME ), uno::Any( aDBName ) );
     806           4 :         mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_URL ), uno::Any( aWorkDir ) );
     807           4 :         mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_FILE_NAME_PREFIX ), uno::Any( aPrefix ));
     808           4 :         if (tablename)
     809             :         {
     810           4 :             mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND_TYPE ), uno::Any( sdb::CommandType::TABLE ) );
     811           4 :             mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND ), uno::Any( OUString::createFromAscii(tablename) ) );
     812           4 :         }
     813           4 :     }
     814             : 
     815           4 :     virtual void executeMailMerge()
     816             :     {
     817           4 :         uno::Any res = mxJob->execute( mSeqMailMergeArgs );
     818             : 
     819           8 :         OUString aCurOutputURL;
     820           8 :         OUString aCurFileNamePrefix;
     821           4 :         const beans::NamedValue *pArguments = mSeqMailMergeArgs.getConstArray();
     822           4 :         bool bOk = true;
     823           4 :         sal_Int32 nArgs = mSeqMailMergeArgs.getLength();
     824             : 
     825          32 :         for (sal_Int32 i = 0; i < nArgs; ++i) {
     826          28 :             const OUString &rName  = pArguments[i].Name;
     827          28 :             const uno::Any &rValue = pArguments[i].Value;
     828             : 
     829             :             // all error checking was already done by the MM job execution
     830          28 :             if (rName == UNO_NAME_OUTPUT_URL)
     831           4 :                 bOk &= rValue >>= aCurOutputURL;
     832          24 :             else if (rName == UNO_NAME_FILE_NAME_PREFIX)
     833           4 :                 bOk &= rValue >>= aCurFileNamePrefix;
     834          20 :             else if (rName == UNO_NAME_OUTPUT_TYPE)
     835           4 :                 bOk &= rValue >>= nCurOutputType;
     836             :         }
     837             : 
     838           4 :         CPPUNIT_ASSERT(bOk);
     839             : 
     840           4 :         if (nCurOutputType == text::MailMergeType::SHELL)
     841             :         {
     842           4 :             CPPUNIT_ASSERT(res >>= mxMMComponent);
     843           4 :             CPPUNIT_ASSERT(mxMMComponent.is());
     844             :         }
     845             :         else
     846             :         {
     847           0 :             CPPUNIT_ASSERT(res == true);
     848           0 :             mxMMComponent = loadFromDesktop( aCurOutputURL + "/" + aCurFileNamePrefix + "0.odt",
     849           0 :                                              "com.sun.star.text.TextDocument");
     850           0 :             CPPUNIT_ASSERT(mxMMComponent.is());
     851           0 :             calcLayout();
     852           4 :         }
     853           4 :     }
     854             : };
     855             : 
     856             : /**
     857             :  * Test whether the expected and actual borderline parameters are equal
     858             :  * and assert if not.
     859             :  *
     860             :  * @param[in]   rExpected    expected borderline object
     861             :  * @param[in]   rActual      actual borderline object
     862             :  * @param[in]   rSourceLine  line from where the assertion is called
     863             :  * Note: This method is the implementatition of CPPUNIT_ASSERT_BORDER_EQUAL, so
     864             :  *       use that macro instead.
     865             : **/
     866         252 : inline void assertBorderEqual(
     867             :     const table::BorderLine2& rExpected, const table::BorderLine2& rActual,
     868             :     const CppUnit::SourceLine& rSourceLine )
     869             : {
     870         252 :     CPPUNIT_NS::assertEquals<util::Color>( rExpected.Color, rActual.Color, rSourceLine, "different Color" );
     871         252 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.InnerLineWidth, rActual.InnerLineWidth, rSourceLine, "different InnerLineWidth" );
     872         252 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.OuterLineWidth, rActual.OuterLineWidth, rSourceLine, "different OuterLineWidth" );
     873         252 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.LineDistance, rActual.LineDistance, rSourceLine, "different LineDistance" );
     874         252 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.LineStyle, rActual.LineStyle, rSourceLine, "different LineStyle" );
     875         252 :     CPPUNIT_NS::assertEquals<sal_Int32>( rExpected.LineWidth, rActual.LineWidth, rSourceLine, "different LineWidth" );
     876         252 : }
     877             : 
     878             : #define CPPUNIT_ASSERT_BORDER_EQUAL(aExpected, aActual) \
     879             :         assertBorderEqual( aExpected, aActual, CPPUNIT_SOURCELINE() ) \
     880             : 
     881             : #endif // INCLUDED_SW_QA_EXTRAS_INC_SWMODELTESTBASE_HXX
     882             : 
     883             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10