LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/qa/extras/inc - swmodeltestbase.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 174 174 100.0 %
Date: 2013-07-09 Functions: 61 62 98.4 %
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             : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
      11             : #include <com/sun/star/frame/Desktop.hpp>
      12             : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
      13             : #include <com/sun/star/text/XPageCursor.hpp>
      14             : #include <com/sun/star/text/XTextDocument.hpp>
      15             : #include <com/sun/star/text/XTextRange.hpp>
      16             : #include <com/sun/star/text/XTextTable.hpp>
      17             : #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
      18             : #include <com/sun/star/table/XCell.hpp>
      19             : 
      20             : #include <test/bootstrapfixture.hxx>
      21             : #include <unotest/macros_test.hxx>
      22             : #include <rtl/ustrbuf.hxx>
      23             : #include <comphelper/processfactory.hxx>
      24             : #include <unotools/tempfile.hxx>
      25             : 
      26             : #include <unotxdoc.hxx>
      27             : #include <docsh.hxx>
      28             : #include <doc.hxx>
      29             : #include <rootfrm.hxx>
      30             : 
      31             : #include <libxml/xmlwriter.h>
      32             : #include <libxml/xpath.h>
      33             : 
      34             : using namespace com::sun::star;
      35             : 
      36             : #define DEFAULT_STYLE "Default Style"
      37             : 
      38             : /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
      39             : class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest
      40             : {
      41             : public:
      42           9 :     SwModelTestBase()
      43           9 :         : mpXmlBuffer(0)
      44             :     {
      45           9 :     }
      46             : 
      47           9 :     ~SwModelTestBase()
      48           9 :     {
      49           9 :     }
      50             : 
      51           9 :     virtual void setUp()
      52             :     {
      53           9 :         test::BootstrapFixture::setUp();
      54             : 
      55           9 :         mxDesktop.set( com::sun::star::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())) );
      56           9 :     }
      57             : 
      58           9 :     virtual void tearDown()
      59             :     {
      60           9 :         if (mxComponent.is())
      61           9 :             mxComponent->dispose();
      62             : 
      63           9 :         test::BootstrapFixture::tearDown();
      64           9 :     }
      65             : 
      66             : private:
      67          12 :     void dumpLayout()
      68             :     {
      69             :         // create the xml writer
      70          12 :         mpXmlBuffer = xmlBufferCreate();
      71          12 :         xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(mpXmlBuffer, 0);
      72          12 :         xmlTextWriterStartDocument(pXmlWriter, NULL, NULL, NULL);
      73             : 
      74             :         // create the dump
      75          12 :         SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
      76          12 :         SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
      77          12 :         SwRootFrm* pLayout = pDoc->GetCurrentLayout();
      78          12 :         pLayout->dumpAsXml(pXmlWriter);
      79             : 
      80             :         // delete xml writer
      81          12 :         xmlTextWriterEndDocument(pXmlWriter);
      82          12 :         xmlFreeTextWriter(pXmlWriter);
      83          12 :     }
      84             : 
      85         397 :     void calcLayout()
      86             :     {
      87         397 :         SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
      88         397 :         SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
      89         397 :         pDoc->GetCurrentViewShell()->CalcLayout();
      90         397 :     }
      91             : 
      92             : 
      93             : protected:
      94             :     /// Get the length of the whole document.
      95          11 :     int getLength()
      96             :     {
      97          11 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
      98          22 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
      99          22 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     100          22 :         OUStringBuffer aBuf;
     101          34 :         while (xParaEnum->hasMoreElements())
     102             :         {
     103          12 :             uno::Reference<container::XEnumerationAccess> xRangeEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
     104          24 :             uno::Reference<container::XEnumeration> xRangeEnum = xRangeEnumAccess->createEnumeration();
     105          40 :             while (xRangeEnum->hasMoreElements())
     106             :             {
     107          16 :                 uno::Reference<text::XTextRange> xRange(xRangeEnum->nextElement(), uno::UNO_QUERY);
     108          16 :                 aBuf.append(xRange->getString());
     109          16 :             }
     110          12 :         }
     111          22 :         return aBuf.getLength();
     112             :     }
     113             : 
     114             :     /// Get a family of styles, see com.sun.star.style.StyleFamilies for possible values.
     115          42 :     uno::Reference<container::XNameAccess> getStyles(OUString aFamily)
     116             :     {
     117          42 :         uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
     118          84 :         uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
     119          42 :         uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(aFamily), uno::UNO_QUERY);
     120          84 :         return xStyleFamily;
     121             :     }
     122             : 
     123             :     /**
     124             :      * Extract a value from the layout dump using an XPath expression and an attribute name.
     125             :      *
     126             :      * If the attribute is omitted, the text of the node is returned.
     127             :      */
     128          66 :     OUString parseDump(OString aXPath, OString aAttribute = OString())
     129             :     {
     130          66 :         if (!mpXmlBuffer)
     131          12 :             dumpLayout();
     132             : 
     133          66 :         xmlDocPtr pXmlDoc = xmlParseMemory((const char*)xmlBufferContent(mpXmlBuffer), xmlBufferLength(mpXmlBuffer));;
     134             : 
     135          66 :         xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
     136          66 :         xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(aXPath.getStr()), pXmlXpathCtx);
     137          66 :         xmlNodeSetPtr pXmlNodes = pXmlXpathObj->nodesetval;
     138          66 :         CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlNodes));
     139          66 :         xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
     140          66 :         OUString aRet;
     141          66 :         if (aAttribute.getLength())
     142           5 :             aRet = OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(aAttribute.getStr())));
     143             :         else
     144          61 :             aRet = OUString::createFromAscii((const char*)XML_GET_CONTENT(pXmlNode));
     145             : 
     146          66 :         xmlFreeDoc(pXmlDoc);
     147             : 
     148          66 :         return aRet;
     149             :     }
     150             : 
     151             :     template< typename T >
     152          78 :     T getProperty( uno::Any obj, const OUString& name ) const
     153             :     {
     154          78 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
     155          78 :         T data = T();
     156          78 :         properties->getPropertyValue( name ) >>= data;
     157          78 :         return data;
     158             :     }
     159             : 
     160             :     template< typename T >
     161         483 :     T getProperty( uno::Reference< uno::XInterface > obj, const OUString& name ) const
     162             :     {
     163         483 :         uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
     164         483 :         T data = T();
     165         483 :         properties->getPropertyValue( name ) >>= data;
     166         483 :         return data;
     167             :     }
     168             : 
     169             :     /// Get number of paragraphs of the document.
     170           1 :     int getParagraphs()
     171             :     {
     172           1 :         uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
     173           2 :         uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
     174           2 :         uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
     175           1 :         int nRet = 0;
     176           4 :         while (xParaEnum->hasMoreElements())
     177             :         {
     178           2 :             xParaEnum->nextElement();
     179           2 :             nRet++;
     180             :         }
     181           2 :         return nRet;
     182             :     }
     183             : 
     184         203 :     uno::Reference<text::XTextContent> getParagraphOrTable(int number, uno::Reference<text::XText> xText = uno::Reference<text::XText>()) const
     185             :     {
     186         203 :         uno::Reference<container::XEnumerationAccess> paraEnumAccess;
     187         203 :         if (xText.is())
     188          14 :             paraEnumAccess.set(xText, uno::UNO_QUERY);
     189             :         else
     190             :         {
     191         189 :             uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
     192         189 :             paraEnumAccess.set(textDocument->getText(), uno::UNO_QUERY);
     193             :         }
     194         406 :         uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
     195         333 :         for( int i = 1;
     196             :              i < number;
     197             :              ++i )
     198         130 :             paraEnum->nextElement();
     199         203 :         uno::Reference< text::XTextContent> const xElem(paraEnum->nextElement(),
     200         203 :                 uno::UNO_QUERY_THROW);
     201         406 :         return xElem;
     202             :     }
     203             : 
     204             :     // Get paragraph (counted from 1), optionally check it contains the given text.
     205         188 :     uno::Reference< text::XTextRange > getParagraph( int number, OUString content = OUString() ) const
     206             :     {
     207             :         uno::Reference<text::XTextRange> const xParagraph(
     208         188 :                 getParagraphOrTable(number), uno::UNO_QUERY_THROW);
     209         188 :         if( !content.isEmpty())
     210          18 :             CPPUNIT_ASSERT_EQUAL( content, xParagraph->getString());
     211         188 :         return xParagraph;
     212             :     }
     213             : 
     214          11 :     uno::Reference<text::XTextRange> getParagraphOfText(int number, uno::Reference<text::XText> xText) const
     215             :     {
     216          11 :         uno::Reference<text::XTextRange> const xParagraph(getParagraphOrTable(number, xText), uno::UNO_QUERY_THROW);
     217          11 :         return xParagraph;
     218             :     }
     219             : 
     220             :     /// Get run (counted from 1) of a paragraph, optionally check it contains the given text.
     221         178 :     uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, OUString content = OUString()) const
     222             :     {
     223         178 :         uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY);
     224         356 :         uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
     225         357 :         for (int i = 1; i < number; ++i)
     226         179 :             xRunEnum->nextElement();
     227         178 :         uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
     228         178 :         if( !content.isEmpty())
     229          27 :             CPPUNIT_ASSERT_EQUAL( content, xRun->getString());
     230         356 :         return xRun;
     231             :     }
     232             : 
     233             :     /// Get math formula string of a run.
     234         114 :     OUString getFormula(uno::Reference<text::XTextRange> xRun) const
     235             :     {
     236         114 :         uno::Reference<container::XContentEnumerationAccess> xContentEnumAccess(xRun, uno::UNO_QUERY);
     237         228 :         uno::Reference<container::XEnumeration> xContentEnum(xContentEnumAccess->createContentEnumeration(""), uno::UNO_QUERY);
     238         228 :         uno::Reference<beans::XPropertySet> xFormula(xContentEnum->nextElement(), uno::UNO_QUERY);
     239         228 :         return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
     240             :     }
     241             : 
     242             :     /// get cell of a table; table can be retrieved with getParagraphOrTable
     243           5 :     uno::Reference<table::XCell> getCell(
     244             :             uno::Reference<uno::XInterface> const& xTableIfc,
     245             :             OUString const& rCell, OUString const& rContent = OUString())
     246             :     {
     247             :         uno::Reference<text::XTextTable> const xTable(xTableIfc,
     248           5 :                 uno::UNO_QUERY_THROW);
     249             :         uno::Reference<table::XCell> const xCell(
     250           5 :                 xTable->getCellByName(rCell), uno::UNO_SET_THROW);
     251           5 :         if (!rContent.isEmpty())
     252             :         {
     253             :             uno::Reference<text::XText> const xCellText(xCell,
     254           3 :                     uno::UNO_QUERY_THROW);
     255           3 :             CPPUNIT_ASSERT_EQUAL(rContent, xCellText->getString());
     256             :         }
     257           5 :         return xCell;
     258             :     }
     259             : 
     260           9 :     void header()
     261             :     {
     262           9 :         std::cerr << "File tested,Execution Time (ms)" << std::endl;
     263           9 :     }
     264             : 
     265         298 :     void load(const char* pDir, const char* pName, bool bCalcLayout = true)
     266             :     {
     267         298 :         if (mxComponent.is())
     268         289 :             mxComponent->dispose();
     269             :         // Output name early, so in the case of a hang, the name of the hanging input file is visible.
     270         298 :         std::cerr << pName << ",";
     271         298 :         m_nStartTime = osl_getGlobalTimer();
     272         298 :         mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName), "com.sun.star.text.TextDocument");
     273         298 :         if (bCalcLayout)
     274         297 :             calcLayout();
     275         298 :     }
     276             : 
     277         100 :     void reload(OUString aFilter)
     278             :     {
     279         100 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     280         200 :         uno::Sequence<beans::PropertyValue> aArgs(1);
     281         100 :         aArgs[0].Name = "FilterName";
     282         100 :         aArgs[0].Value <<= aFilter;
     283         200 :         utl::TempFile aTempFile;
     284         100 :         aTempFile.EnableKillingFile();
     285         100 :         xStorable->storeToURL(aTempFile.GetURL(), aArgs);
     286         200 :         uno::Reference<lang::XComponent> xComponent(xStorable, uno::UNO_QUERY);
     287         100 :         xComponent->dispose();
     288         100 :         mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
     289         100 :         if (mpXmlBuffer)
     290             :         {
     291           4 :             xmlBufferFree(mpXmlBuffer);
     292           4 :             mpXmlBuffer = 0;
     293             :         }
     294         200 :         calcLayout();
     295         100 :     }
     296             : 
     297             :     /// Save the loaded document to a tempfile. Can be used to check the resulting docx/odt directly as a ZIP file.
     298           4 :     void save(OUString aFilter, utl::TempFile& rTempFile)
     299             :     {
     300           4 :         rTempFile.EnableKillingFile();
     301           4 :         uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
     302           8 :         uno::Sequence<beans::PropertyValue> aFilterArgs(1);
     303           4 :         aFilterArgs[0].Name = "FilterName";
     304           4 :         aFilterArgs[0].Value <<= aFilter;
     305           8 :         xStorable->storeToURL(rTempFile.GetURL(), aFilterArgs);
     306           4 :     }
     307             : 
     308         298 :     void finish()
     309             :     {
     310         298 :         sal_uInt32 nEndTime = osl_getGlobalTimer();
     311         298 :         std::cerr << (nEndTime - m_nStartTime) << std::endl;
     312         298 :         if (mpXmlBuffer)
     313             :         {
     314           8 :             xmlBufferFree(mpXmlBuffer);
     315           8 :             mpXmlBuffer = 0;
     316             :         }
     317         298 :     }
     318             : 
     319             :     /// Get page count.
     320           9 :     int getPages()
     321             :     {
     322           9 :         uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
     323          18 :         uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
     324          18 :         uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
     325           9 :         xCursor->jumpToLastPage();
     326          18 :         return xCursor->getPage();
     327             :     }
     328             : 
     329             :     uno::Reference<lang::XComponent> mxComponent;
     330             :     xmlBufferPtr mpXmlBuffer;
     331             : 
     332             :     template< typename T >
     333             :     struct MethodEntry
     334             :     {
     335             :         const char* pName;
     336             :         void (T::*pMethod)();
     337             :     };
     338             :     sal_uInt32 m_nStartTime;
     339             : };
     340             : 
     341             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10