LCOV - code coverage report
Current view: top level - sw/qa/extras/inc - swmodeltestbase.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 340 348 97.7 %
Date: 2015-06-13 12:38:46 Functions: 107 110 97.3 %
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             : 
      31             : #include <test/bootstrapfixture.hxx>
      32             : #include <test/xmltesttools.hxx>
      33             : #include <unotest/macros_test.hxx>
      34             : #include <unotools/ucbstreamhelper.hxx>
      35             : #include <rtl/strbuf.hxx>
      36             : #include <rtl/ustrbuf.hxx>
      37             : #include <rtl/byteseq.hxx>
      38             : #include <comphelper/processfactory.hxx>
      39             : #include <unotools/tempfile.hxx>
      40             : #include <unotools/localfilehelper.hxx>
      41             : #include <unotools/mediadescriptor.hxx>
      42             : #include <dbmgr.hxx>
      43             : #include <unoprnms.hxx>
      44             : 
      45             : #include <unotxdoc.hxx>
      46             : #include <docsh.hxx>
      47             : #include <doc.hxx>
      48             : #include <IDocumentLayoutAccess.hxx>
      49             : #include <rootfrm.hxx>
      50             : 
      51             : using namespace css;
      52             : 
      53             : #define DEFAULT_STYLE "Default Style"
      54             : 
      55             : /**
      56             :  * Macro to declare a new test (with full round-trip. To test
      57             :  * import only use the DECLARE_SW_IMPORT_TEST macro instead).
      58             :  * In order to add a new test, one only needs to use this macro
      59             :  * and then specify the test content, like this:
      60             :  *
      61             :  * DECLARE_SW_ROUNDTRIP_TEST(MyTest, "myfilename.docx", Test)
      62             :  * {
      63             :  *      CPPUNIT_ASSERT_EQUAL(blabla);
      64             :  * }
      65             :  *
      66             :  */
      67             : #define DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, BaseClass) \
      68             :     class TestName : public BaseClass { \
      69             :         protected:\
      70             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString(#TestName); } \
      71             :         public:\
      72             :     CPPUNIT_TEST_SUITE(TestName); \
      73             :     CPPUNIT_TEST(Import); \
      74             :     CPPUNIT_TEST(Import_Export_Import); \
      75             :     CPPUNIT_TEST_SUITE_END(); \
      76             :     \
      77             :     void Import() { \
      78             :         executeImportTest(filename);\
      79             :     }\
      80             :     void Import_Export_Import() {\
      81             :         executeImportExportImportTest(filename);\
      82             :     }\
      83             :     void verify() SAL_OVERRIDE;\
      84             :     }; \
      85             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
      86             :     void TestName::verify()
      87             : 
      88             : #define DECLARE_OOXMLIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      89             : #define DECLARE_OOXMLEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      90             : #define DECLARE_RTFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      91             : #define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      92             : #define DECLARE_ODFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
      93             : #define DECLARE_ODFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      94             : #define DECLARE_WW8EXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
      95             : 
      96             : #define DECLARE_SW_IMPORT_TEST(TestName, filename, BaseClass) \
      97             :     class TestName : public BaseClass { \
      98             :         protected:\
      99             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString(#TestName); } \
     100             :         public:\
     101             :     CPPUNIT_TEST_SUITE(TestName); \
     102             :     CPPUNIT_TEST(Import); \
     103             :     CPPUNIT_TEST_SUITE_END(); \
     104             :     \
     105             :     void Import() { \
     106             :         executeImportTest(filename);\
     107             :     }\
     108             :     void verify() SAL_OVERRIDE;\
     109             :     }; \
     110             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
     111             :     void TestName::verify()
     112             : 
     113             : #define DECLARE_SW_EXPORT_TEST(TestName, filename, BaseClass) \
     114             :     class TestName : public BaseClass { \
     115             :         protected:\
     116             :     virtual OUString getTestName() SAL_OVERRIDE { return OUString(#TestName); } \
     117             :         public:\
     118             :     CPPUNIT_TEST_SUITE(TestName); \
     119             :     CPPUNIT_TEST(Import_Export); \
     120             :     CPPUNIT_TEST_SUITE_END(); \
     121             :     \
     122             :     void Import_Export() {\
     123             :         executeImportExport(filename);\
     124             :     }\
     125             :     void verify() SAL_OVERRIDE;\
     126             :     }; \
     127             :     CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \
     128             :     void TestName::verify()
     129             : 
     130             : /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
     131             : class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
     132             : {
     133             : private:
     134             :     OUString maFilterOptions;
     135             : 
     136             : protected:
     137             :     uno::Reference< lang::XComponent > mxComponent;
     138             : 
     139             :     xmlBufferPtr mpXmlBuffer;
     140             :     const char* mpTestDocumentPath;
     141             :     const char* mpFilter;
     142             : 
     143             :     sal_uInt32 mnStartTime;
     144             :     utl::TempFile maTempFile;
     145             :     bool mbExported; ///< Does maTempFile already contain something useful?
     146             : 
     147             : protected:
     148           0 :     virtual OUString getTestName() { return OUString(); }
     149             : 
     150             : public:
     151             :     OUString& getFilterOptions()
     152             :     {
     153             :         return maFilterOptions;
     154             :     }
     155          15 :     void setFilterOptions(const OUString &rFilterOptions)
     156             :     {
     157          15 :         maFilterOptions = rFilterOptions;
     158          15 :     }
     159             : 
     160        1645 :     SwModelTestBase(const char* pTestDocumentPath = "", const char* pFilter = "")
     161             :         : mpXmlBuffer(0)
     162             :         , mpTestDocumentPath(pTestDocumentPath)
     163             :         , mpFilter(pFilter)
     164             :         , mnStartTime(0)
     165        1645 :         , mbExported(false)
     166             :     {
     167        1645 :         maTempFile.EnableKillingFile();
     168        1645 :     }
     169             : 
     170        1645 :     virtual ~SwModelTestBase()
     171        1645 :     {}
     172             : 
     173        1645 :     virtual void setUp() SAL_OVERRIDE
     174             :     {
     175        1645 :         test::BootstrapFixture::setUp();
     176             : 
     177        1645 :         mxDesktop.set(css::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())));
     178        1645 :     }
     179             : 
     180        1645 :     virtual void tearDown() SAL_OVERRIDE
     181             :     {
     182        1645 :         if (mxComponent.is())
     183        1561 :             mxComponent->dispose();
     184             : 
     185        1645 :         test::BootstrapFixture::tearDown();
     186        1645 :     }
     187             : 
     188             : protected:
     189             :     /**
     190             :      * Helper func used by each unit test to test the 'import' code.
     191             :      * (Loads the requested file and then calls 'verify' method)
     192             :      */
     193        1001 :     void executeImportTest(const char* filename)
     194             :     {
     195             :         // If the testcase is stored in some other format, it's pointless to test.
     196        1001 :         if (mustTestImportOf(filename))
     197             :         {
     198         920 :             maTempFile.EnableKillingFile(false);
     199         920 :             header();
     200         920 :             preTest(filename);
     201         920 :             load(mpTestDocumentPath, filename);
     202         920 :             postTest(filename);
     203         920 :             verify();
     204         920 :             finish();
     205         920 :             maTempFile.EnableKillingFile();
     206             :         }
     207        1001 :     }
     208             : 
     209             :     /**
     210             :      * Helper func used by each unit test to test the 'export' code.
     211             :      * (Loads the requested file, save it to temp file, load the
     212             :      * temp file and then calls 'verify' method)
     213             :      */
     214         567 :     void executeImportExportImportTest(const char* filename)
     215             :     {
     216         567 :         maTempFile.EnableKillingFile(false);
     217         567 :         header();
     218         567 :         preTest(filename);
     219         567 :         load(mpTestDocumentPath, filename);
     220         567 :         postLoad(filename);
     221         567 :         reload(mpFilter, filename);
     222         567 :         postTest(filename);
     223         567 :         verify();
     224         567 :         finish();
     225         567 :         maTempFile.EnableKillingFile();
     226         567 :     }
     227             : 
     228             :     /**
     229             :      * Helper func used by each unit test to test the 'export' code.
     230             :      * (Loads the requested file for document base (this represents
     231             :      * the initial document condition), exports with the desired
     232             :      * export filter and then calls 'verify' method)
     233             :      */
     234          10 :     void executeImportExport(const char* filename)
     235             :     {
     236          10 :         maTempFile.EnableKillingFile(false);
     237          10 :         header();
     238          10 :         preTest(filename);
     239          10 :         load(mpTestDocumentPath, filename);
     240          10 :         save(OUString::createFromAscii(mpFilter), maTempFile);
     241          10 :         maTempFile.EnableKillingFile(false);
     242          10 :         postTest(filename);
     243          10 :         verify();
     244          10 :         finish();
     245          10 :         maTempFile.EnableKillingFile();
     246          10 :     }
     247             : 
     248             :     /**
     249             :      * Function overridden by unit test. See DECLARE_SW_*_TEST macros
     250             :      */
     251           0 :     virtual void verify()
     252             :     {
     253           0 :         CPPUNIT_FAIL( "verify method must be overridden" );
     254           0 :     }
     255             : 
     256             :     /**
     257             :      * Override this function if interested in skipping import test for this file
     258             :      */
     259         434 :      virtual bool mustTestImportOf(const char* /* filename */) const
     260             :      {
     261         434 :         return true;
     262             :      }
     263             :     /**
     264             :      * Override this function if some special filename-specific setup is needed
     265             :      */
     266        1083 :     virtual void preTest(const char* /*filename*/)
     267             :     {
     268        1083 :     }
     269             : 
     270             :     /// Override this function if some special file-specific setup is needed during export test: after load, but before save.
     271         484 :     virtual void postLoad(const char* /*pFilename*/)
     272             :     {
     273         484 :     }
     274             : 
     275             :     /**
     276             :      * Override this function if some special filename-specific teardown is needed
     277             :      */
     278        1083 :     virtual void postTest(const char* /*filename*/)
     279             :     {
     280        1083 :     }
     281             : 
     282             :     /**
     283             :      * Override this function if calcing layout is not needed
     284             :      */
     285        2127 :     virtual bool mustCalcLayoutOf(const char* /*filename*/)
     286             :     {
     287        2127 :         return true;
     288             :     }
     289             : 
     290             :     /**
     291             :      * Override this function if validation is wanted
     292             :      */
     293         425 :     virtual bool mustValidate(const char* /*filename*/) const
     294             :     {
     295         425 :         return false;
     296             :     }
     297             : 
     298             : private:
     299          52 :     void dumpLayout()
     300             :     {
     301             :         // create the xml writer
     302          52 :         mpXmlBuffer = xmlBufferCreate();
     303          52 :         xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(mpXmlBuffer, 0);
     304          52 :         xmlTextWriterStartDocument(pXmlWriter, NULL, NULL, NULL);
     305             : 
     306             :         // create the dump
     307          52 :         SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
     308          52 :         CPPUNIT_ASSERT(pTextDoc);
     309          52 :         SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
     310          52 :         SwRootFrm* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     311          52 :         pLayout->dumpAsXml(pXmlWriter);
     312             : 
     313             :         // delete xml writer
     314          52 :         xmlTextWriterEndDocument(pXmlWriter);
     315          52 :         xmlFreeTextWriter(pXmlWriter);
     316          52 :     }
     317             : 
     318             : protected:
     319        3652 :     void discardDumpedLayout()
     320             :     {
     321        3652 :         if (mpXmlBuffer)
     322             :         {
     323          50 :             xmlBufferFree(mpXmlBuffer);
     324          50 :             mpXmlBuffer = 0;
     325             :         }
     326        3652 :     }
     327             : 
     328        2144 :     void calcLayout()
     329             :     {
     330        2144 :         SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
     331        2144 :         CPPUNIT_ASSERT(pTextDoc);
     332        2144 :         SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
     333        2144 :         pDoc->getIDocumentLayoutAccess().GetCurrentViewShell()->CalcLayout();
     334        2144 :     }
     335             : 
     336             :     /// Get the length of the whole document.
     337           9 :     int getLength()
     338             :     {
     339           9 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     340          18 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     341          18 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     342          18 :         OUStringBuffer aBuf;
     343          28 :         while (xParaEnum->hasMoreElements())
     344             :         {
     345          10 :             uno::Reference<container::XEnumerationAccess> xRangeEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
     346          20 :             uno::Reference<container::XEnumeration> xRangeEnum = xRangeEnumAccess->createEnumeration();
     347          34 :             while (xRangeEnum->hasMoreElements())
     348             :             {
     349          14 :                 uno::Reference<text::XTextRange> xRange(xRangeEnum->nextElement(), uno::UNO_QUERY);
     350          14 :                 aBuf.append(xRange->getString());
     351          14 :             }
     352          10 :         }
     353          18 :         return aBuf.getLength();
     354             :     }
     355             : 
     356             :     /// Get a family of styles, see com.sun.star.style.StyleFamilies for possible values.
     357         130 :     uno::Reference<container::XNameAccess> getStyles(const OUString& aFamily)
     358             :     {
     359         130 :         uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
     360         260 :         uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     361         130 :         uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(aFamily), uno::UNO_QUERY);
     362         260 :         return xStyleFamily;
     363             :     }
     364             : 
     365             :     /// Get a family of auto styles, see com.sun.star.style.StyleFamilies for possible values.
     366           2 :     uno::Reference<style::XAutoStyleFamily> getAutoStyles(const OUString& aFamily)
     367             :     {
     368           2 :         uno::Reference< style::XAutoStylesSupplier > xAutoStylesSupplier(mxComponent, uno::UNO_QUERY);
     369           4 :         uno::Reference< style::XAutoStyles > xAutoStyles(xAutoStylesSupplier->getAutoStyles());
     370           2 :         uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(xAutoStyles->getByName(aFamily), uno::UNO_QUERY);
     371           4 :         return xAutoStyleFamily;
     372             :     }
     373             : 
     374             :     /// Similar to parseExport(), but this gives the xmlDocPtr of the layout dump.
     375         190 :     xmlDocPtr parseLayoutDump()
     376             :     {
     377         190 :         if (!mpXmlBuffer)
     378          52 :             dumpLayout();
     379             : 
     380         190 :         return xmlParseMemory(reinterpret_cast<const char*>(xmlBufferContent(mpXmlBuffer)), xmlBufferLength(mpXmlBuffer));;
     381             :     }
     382             : 
     383             :     /**
     384             :      * Extract a value from the layout dump using an XPath expression and an attribute name.
     385             :      *
     386             :      * If the attribute is omitted, the text of the node is returned.
     387             :      */
     388         188 :     OUString parseDump(const OString& aXPath, const OString& aAttribute = OString())
     389             :     {
     390         188 :         xmlDocPtr pXmlDoc = parseLayoutDump();
     391             : 
     392         188 :         xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
     393         188 :         xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(aXPath.getStr()), pXmlXpathCtx);
     394         188 :         xmlNodeSetPtr pXmlNodes = pXmlXpathObj->nodesetval;
     395         188 :         CPPUNIT_ASSERT_EQUAL_MESSAGE("parsing dump failed", 1, xmlXPathNodeSetGetLength(pXmlNodes));
     396         188 :         xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
     397         188 :         OUString aRet;
     398         188 :         if (aAttribute.getLength())
     399          60 :             aRet = OUString::createFromAscii(reinterpret_cast<char*>(xmlGetProp(pXmlNode, BAD_CAST(aAttribute.getStr()))));
     400             :         else
     401         128 :             aRet = OUString::createFromAscii(reinterpret_cast<char*>(xmlNodeGetContent(pXmlNode)));
     402             : 
     403         188 :         xmlFreeDoc(pXmlDoc);
     404             : 
     405         188 :         return aRet;
     406             :     }
     407             : 
     408             :     template< typename T >
     409         113 :     T getProperty( const uno::Any& obj, const OUString& name ) const
     410             :     {
     411         113 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY_THROW );
     412         113 :         T data = T();
     413         113 :         if (!(properties->getPropertyValue(name) >>= data))
     414             :         {
     415           0 :             CPPUNIT_FAIL("the property is of unexpected type or void");
     416             :         }
     417         113 :         return data;
     418             :     }
     419             : 
     420             :     template< typename T >
     421        2098 :     T getProperty( const uno::Reference< uno::XInterface >& obj, const OUString& name ) const
     422             :     {
     423        2098 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY_THROW );
     424        2098 :         T data = T();
     425        2098 :         if (!(properties->getPropertyValue(name) >>= data))
     426             :         {
     427           0 :             CPPUNIT_FAIL("the property is of unexpected type or void");
     428             :         }
     429        2098 :         return data;
     430             :     }
     431             : 
     432          18 :     bool hasProperty(const uno::Reference<uno::XInterface>& obj, const OUString& name) const
     433             :     {
     434          18 :         uno::Reference<beans::XPropertySet> properties(obj, uno::UNO_QUERY_THROW);
     435          18 :         return properties->getPropertySetInfo()->hasPropertyByName(name);
     436             :     }
     437             : 
     438             :     /// Get number of paragraphs of the document.
     439           5 :     int getParagraphs()
     440             :     {
     441           5 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     442          10 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     443          10 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     444           5 :         int nRet = 0;
     445          23 :         while (xParaEnum->hasMoreElements())
     446             :         {
     447          13 :             xParaEnum->nextElement();
     448          13 :             nRet++;
     449             :         }
     450          10 :         return nRet;
     451             :     }
     452             : 
     453         744 :     uno::Reference<text::XTextContent> getParagraphOrTable(int number, uno::Reference<text::XText> xText = uno::Reference<text::XText>()) const
     454             :     {
     455         744 :         uno::Reference<container::XEnumerationAccess> paraEnumAccess;
     456         744 :         if (xText.is())
     457          86 :             paraEnumAccess.set(xText, uno::UNO_QUERY);
     458             :         else
     459             :         {
     460         658 :             uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
     461         658 :             paraEnumAccess.set(textDocument->getText(), uno::UNO_QUERY);
     462             :         }
     463        1488 :         uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
     464        1685 :         for( int i = 1;
     465             :              i < number;
     466             :              ++i )
     467         941 :             paraEnum->nextElement();
     468         744 :         uno::Reference< text::XTextContent> const xElem(paraEnum->nextElement(),
     469         744 :                 uno::UNO_QUERY_THROW);
     470        1487 :         return xElem;
     471             :     }
     472             : 
     473             :     // Get paragraph (counted from 1), optionally check it contains the given text.
     474         646 :     uno::Reference< text::XTextRange > getParagraph( int number, const OUString& content = OUString() ) const
     475             :     {
     476             :         uno::Reference<text::XTextRange> const xParagraph(
     477         646 :                 getParagraphOrTable(number), uno::UNO_QUERY_THROW);
     478         645 :         if( !content.isEmpty())
     479          55 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "paragraph does not have expected content", content, xParagraph->getString());
     480         645 :         return xParagraph;
     481             :     }
     482             : 
     483          77 :     uno::Reference<text::XTextRange> getParagraphOfText(int number, uno::Reference<text::XText> xText, const OUString& content = OUString()) const
     484             :     {
     485          77 :         uno::Reference<text::XTextRange> const xParagraph(getParagraphOrTable(number, xText), uno::UNO_QUERY_THROW);
     486          77 :         if (!content.isEmpty())
     487          10 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "paragraph does not contain expected content", content, xParagraph->getString());
     488          77 :         return xParagraph;
     489             :     }
     490             : 
     491             :     /// Get run (counted from 1) of a paragraph, optionally check it contains the given text.
     492         787 :     uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, const OUString& content = OUString()) const
     493             :     {
     494         787 :         uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY);
     495        1574 :         uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     496        3373 :         for (int i = 1; i < number; ++i)
     497        2586 :             xRunEnum->nextElement();
     498         787 :         uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
     499         787 :         if( !content.isEmpty())
     500          55 :             CPPUNIT_ASSERT_EQUAL_MESSAGE( "run does not contain expected content", content, xRun->getString());
     501        1574 :         return xRun;
     502             :     }
     503             : 
     504             :     /// Get math formula string of a run.
     505         115 :     OUString getFormula(uno::Reference<text::XTextRange> xRun) const
     506             :     {
     507         115 :         uno::Reference<container::XContentEnumerationAccess> xContentEnumAccess(xRun, uno::UNO_QUERY);
     508         230 :         uno::Reference<container::XEnumeration> xContentEnum(xContentEnumAccess->createContentEnumeration(""), uno::UNO_QUERY);
     509         230 :         uno::Reference<beans::XPropertySet> xFormula(xContentEnum->nextElement(), uno::UNO_QUERY);
     510         230 :         return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
     511             :     }
     512             : 
     513             :     /// get cell of a table; table can be retrieved with getParagraphOrTable
     514           7 :     uno::Reference<table::XCell> getCell(
     515             :             uno::Reference<uno::XInterface> const& xTableIfc,
     516             :             OUString const& rCell, OUString const& rContent = OUString())
     517             :     {
     518             :         uno::Reference<text::XTextTable> const xTable(xTableIfc,
     519           7 :                 uno::UNO_QUERY_THROW);
     520             :         uno::Reference<table::XCell> const xCell(
     521           7 :                 xTable->getCellByName(rCell), uno::UNO_SET_THROW);
     522           7 :         if (!rContent.isEmpty())
     523             :         {
     524             :             uno::Reference<text::XText> const xCellText(xCell,
     525           3 :                     uno::UNO_QUERY_THROW);
     526           3 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("cell does not contain expected content", rContent, xCellText->getString());
     527             :         }
     528           7 :         return xCell;
     529             :     }
     530             : 
     531             :     /// Get shape (counted from 1)
     532         399 :     uno::Reference<drawing::XShape> getShape(int number)
     533             :     {
     534         399 :         uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     535         798 :         uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
     536         399 :         uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(number - 1), uno::UNO_QUERY);
     537         795 :         return xShape;
     538             :     }
     539             : 
     540             :     /// Get shape by name
     541           6 :     uno::Reference<drawing::XShape> getShapeByName(const OUString& aName)
     542             :     {
     543           6 :         uno::Reference<drawing::XShape> xRet;
     544             : 
     545          12 :         uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     546          12 :         uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
     547          12 :         for (sal_Int32 i = 0; i < xDrawPage->getCount(); ++i)
     548             :         {
     549          12 :             uno::Reference<container::XNamed> xShape(xDrawPage->getByIndex(i), uno::UNO_QUERY);
     550          12 :             if (xShape->getName() == aName)
     551             :             {
     552           6 :                 xRet.set(xShape, uno::UNO_QUERY);
     553           6 :                 break;
     554             :             }
     555           6 :         }
     556             : 
     557          12 :         return xRet;
     558             :     }
     559             :     /// Get TextFrame by name
     560           6 :     uno::Reference<drawing::XShape> getTextFrameByName(const OUString& aName)
     561             :     {
     562           6 :         uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
     563          12 :         uno::Reference<container::XNameAccess> xNameAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
     564           6 :         uno::Reference<drawing::XShape> xShape(xNameAccess->getByName(aName), uno::UNO_QUERY);
     565          12 :         return xShape;
     566             :     }
     567             : 
     568        1506 :     void header()
     569             :     {
     570        1506 :         std::cout << "File tested,Execution Time (ms)" << std::endl;
     571        1506 :     }
     572             : 
     573        1554 :     void load(const char* pDir, const char* pName)
     574             :     {
     575        1554 :         if (mxComponent.is())
     576           0 :             mxComponent->dispose();
     577             :         // Output name early, so in the case of a hang, the name of the hanging input file is visible.
     578        1554 :         std::cout << pName << ",";
     579        1554 :         mnStartTime = osl_getGlobalTimer();
     580        1554 :         mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName), "com.sun.star.text.TextDocument");
     581        1554 :         discardDumpedLayout();
     582        1554 :         if (mustCalcLayoutOf(pName))
     583        1553 :             calcLayout();
     584        1554 :     }
     585             : 
     586         569 :     void reload(const char* pFilter, const char* filename)
     587             :     {
     588         569 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     589        1138 :         OUString aFilterName = OUString::createFromAscii(pFilter);
     590        1138 :         utl::MediaDescriptor aMediaDescriptor;
     591         569 :         aMediaDescriptor["FilterName"] <<= aFilterName;
     592         569 :         if (!maFilterOptions.isEmpty())
     593           0 :             aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
     594         569 :         xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
     595        1138 :         uno::Reference<lang::XComponent> xComponent(xStorable, uno::UNO_QUERY);
     596         569 :         xComponent->dispose();
     597         569 :         mbExported = true;
     598         569 :         mxComponent = loadFromDesktop(maTempFile.GetURL(), "com.sun.star.text.TextDocument");
     599         569 :         if (mustValidate(filename))
     600             :         {
     601          18 :             if(aFilterName == "Office Open XML Text")
     602             :             {
     603             :                 // too many validation errors right now
     604           6 :                 validate(maTempFile.GetFileName(), test::OOXML);
     605             :             }
     606          12 :             else if(aFilterName == "writer8")
     607             :             {
     608             :                 // still a few validation errors
     609          12 :                 validate(maTempFile.GetFileName(), test::ODF);
     610             :             }
     611             :         }
     612         569 :         discardDumpedLayout();
     613         569 :         if (mustCalcLayoutOf(filename))
     614        1137 :             calcLayout();
     615         569 :     }
     616             : 
     617             :     /// Save the loaded document to a tempfile. Can be used to check the resulting docx/odt directly as a ZIP file.
     618          11 :     void save(const OUString& aFilterName, utl::TempFile& rTempFile)
     619             :     {
     620          11 :         rTempFile.EnableKillingFile();
     621          11 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     622          22 :         utl::MediaDescriptor aMediaDescriptor;
     623          11 :         aMediaDescriptor["FilterName"] <<= aFilterName;
     624          11 :         if (!maFilterOptions.isEmpty())
     625           3 :             aMediaDescriptor["FilterOptions"] <<= maFilterOptions;
     626          22 :         xStorable->storeToURL(rTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
     627          11 :     }
     628             : 
     629        1506 :     void finish()
     630             :     {
     631        1506 :         sal_uInt32 nEndTime = osl_getGlobalTimer();
     632        1506 :         std::cout << (nEndTime - mnStartTime) << std::endl;
     633        1506 :         discardDumpedLayout();
     634        1506 :     }
     635             : 
     636             :     /// Get page count.
     637          36 :     int getPages()
     638             :     {
     639          36 :         uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     640          72 :         uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
     641          72 :         uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
     642          36 :         xCursor->jumpToLastPage();
     643          72 :         return xCursor->getPage();
     644             :     }
     645             : 
     646             :     /**
     647             :      * Given that some problem doesn't affect the result in the importer, we
     648             :      * test the resulting file directly, by opening the zip file, parsing an
     649             :      * xml stream, and asserting an XPath expression. This method returns the
     650             :      * xml stream, so that you can do the asserting.
     651             :      */
     652         571 :     xmlDocPtr parseExport(const OUString& rStreamName = OUString("word/document.xml"))
     653             :     {
     654         571 :         if (!mbExported)
     655         265 :             return 0;
     656             : 
     657         306 :         return parseExportInternal( maTempFile.GetURL(), rStreamName );
     658             :     }
     659             : 
     660         307 :     xmlDocPtr parseExportInternal( const OUString& url, const OUString& rStreamName )
     661             :     {
     662             :         // Read the XML stream we're interested in.
     663         307 :         uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), url);
     664         614 :         uno::Reference<io::XInputStream> xInputStream(xNameAccess->getByName(rStreamName), uno::UNO_QUERY);
     665         614 :         boost::shared_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
     666             : 
     667         307 :         xmlDocPtr pXmlDoc = parseXmlStream(pStream.get());
     668         307 :         pXmlDoc->name = reinterpret_cast<char *>(xmlStrdup(reinterpret_cast<xmlChar const *>(OUStringToOString(maTempFile.GetURL(), RTL_TEXTENCODING_UTF8).getStr())));
     669         614 :         return pXmlDoc;
     670             :     }
     671             : 
     672             :     /**
     673             :      * Helper method to return nodes represented by rXPath.
     674             :      */
     675        1162 :     virtual void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) SAL_OVERRIDE
     676             :     {
     677             :         // docx
     678        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main"));
     679        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml"));
     680        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006"));
     681        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape"));
     682        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"));
     683        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"));
     684        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("wp14"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"));
     685        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main"));
     686        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("pic"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/picture"));
     687        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rels"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships"));
     688        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w14"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordml"));
     689        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("m"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/math"));
     690        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types"));
     691        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("lc"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas"));
     692        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("extended-properties"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"));
     693        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"), BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main"));
     694        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("o"), BAD_CAST("urn:schemas-microsoft-com:office:office"));
     695             :         // odt
     696        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
     697        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("style"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0"));
     698        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0"));
     699        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0"));
     700        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("draw"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"));
     701        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("fo"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"));
     702        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xlink"), BAD_CAST("http://www.w3.org/1999/xlink"));
     703        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dc"), BAD_CAST("http://purl.org/dc/elements/1.1/"));
     704        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("meta"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:meta:1.0"));
     705        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("number"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"));
     706        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("svg"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"));
     707        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("chart"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:chart:1.0"));
     708        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dr3d"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"));
     709        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("math"), BAD_CAST("http://www.w3.org/1998/Math/MathML"));
     710        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("form"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:form:1.0"));
     711        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("script"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:script:1.0"));
     712        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ooo"), BAD_CAST("http://openoffice.org/2004/office"));
     713        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ooow"), BAD_CAST("http://openoffice.org/2004/writer"));
     714        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("oooc"), BAD_CAST("http://openoffice.org/2004/calc"));
     715        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("dom"), BAD_CAST("http://www.w3.org/2001/xml-events"));
     716        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xforms"), BAD_CAST("http://www.w3.org/2002/xforms"));
     717        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xsd"), BAD_CAST("http://www.w3.org/2001/XMLSchema"));
     718        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xsi"), BAD_CAST("http://www.w3.org/2001/XMLSchema-instance"));
     719        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rpt"), BAD_CAST("http://openoffice.org/2005/report"));
     720        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("of"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:of:1.2"));
     721        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("xhtml"), BAD_CAST("http://www.w3.org/1999/xhtml"));
     722        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("grddl"), BAD_CAST("http://www.w3.org/2003/g/data-view#"));
     723        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("officeooo"), BAD_CAST("http://openoffice.org/2009/office"));
     724        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("tableooo"), BAD_CAST("http://openoffice.org/2009/table"));
     725        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("drawooo"), BAD_CAST("http://openoffice.org/2010/draw"));
     726        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("calcext"), BAD_CAST("urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"));
     727        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("loext"), BAD_CAST("urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"));
     728        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("field"), BAD_CAST("urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"));
     729        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("formx"), BAD_CAST("urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"));
     730        1162 :         xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("css3t"), BAD_CAST("http://www.w3.org/TR/css3-text/"));
     731        1162 :     }
     732             : };
     733             : 
     734             : /**
     735             :  * Test whether the expected and actual borderline parameters are equal
     736             :  * and assert if not.
     737             :  *
     738             :  * @param[in]   rExpected    expected borderline object
     739             :  * @param[in]   rActual      actual borderline object
     740             :  * @param[in]   rSourceLine  line from where the assertion is called
     741             :  * Note: This method is the implementatition of CPPUNIT_ASSERT_BORDER_EQUAL, so
     742             :  *       use that macro instead.
     743             : **/
     744         126 : inline void assertBorderEqual(
     745             :     const table::BorderLine2& rExpected, const table::BorderLine2& rActual,
     746             :     const CppUnit::SourceLine& rSourceLine )
     747             : {
     748         126 :     CPPUNIT_NS::assertEquals<util::Color>( rExpected.Color, rActual.Color, rSourceLine, "different Color" );
     749         126 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.InnerLineWidth, rActual.InnerLineWidth, rSourceLine, "different InnerLineWidth" );
     750         126 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.OuterLineWidth, rActual.OuterLineWidth, rSourceLine, "different OuterLineWidth" );
     751         126 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.LineDistance, rActual.LineDistance, rSourceLine, "different LineDistance" );
     752         126 :     CPPUNIT_NS::assertEquals<sal_Int16>( rExpected.LineStyle, rActual.LineStyle, rSourceLine, "different LineStyle" );
     753         126 :     CPPUNIT_NS::assertEquals<sal_Int32>( rExpected.LineWidth, rActual.LineWidth, rSourceLine, "different LineWidth" );
     754         126 : }
     755             : 
     756             : #define CPPUNIT_ASSERT_BORDER_EQUAL(aExpected, aActual) \
     757             :         assertBorderEqual( aExpected, aActual, CPPUNIT_SOURCELINE() ) \
     758             : 
     759             : #endif // INCLUDED_SW_QA_EXTRAS_INC_SWMODELTESTBASE_HXX
     760             : 
     761             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11