LCOV - code coverage report
Current view: top level - editeng/qa/unit - core-test.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 307 324 94.8 %
Date: 2015-06-13 12:38:46 Functions: 33 39 84.6 %
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 "test/bootstrapfixture.hxx"
      11             : 
      12             : #include <cppunit/TestFixture.h>
      13             : #include <cppunit/extensions/HelperMacros.h>
      14             : 
      15             : #include "svl/itempool.hxx"
      16             : #include "editeng/eerdll.hxx"
      17             : #include "editeng/eerdll2.hxx"
      18             : #include "editeng/editeng.hxx"
      19             : #include "editeng/eeitem.hxx"
      20             : #include "editeng/editids.hrc"
      21             : #include "editeng/editdoc.hxx"
      22             : #include "editeng/svxacorr.hxx"
      23             : #include "editeng/unofield.hxx"
      24             : #include "editeng/wghtitem.hxx"
      25             : #include "editeng/postitem.hxx"
      26             : #include "editeng/section.hxx"
      27             : #include "editeng/editobj.hxx"
      28             : #include "editeng/flditem.hxx"
      29             : #include "svl/srchitem.hxx"
      30             : #include "rtl/strbuf.hxx"
      31             : 
      32             : #include <com/sun/star/text/textfield/Type.hpp>
      33             : 
      34             : #include <boost/scoped_ptr.hpp>
      35             : 
      36             : using namespace com::sun::star;
      37             : 
      38             : namespace {
      39             : 
      40          10 : class Test : public test::BootstrapFixture
      41             : {
      42             : public:
      43             :     Test();
      44             : 
      45             :     virtual void setUp() SAL_OVERRIDE;
      46             :     virtual void tearDown() SAL_OVERRIDE;
      47             : 
      48             :     void testConstruction();
      49             : 
      50             :     /// Test UNO service class that implements text field items.
      51             :     void testUnoTextFields();
      52             : 
      53             :     /// AutoCorrect tests
      54             :     void testAutocorrect();
      55             : 
      56             :     /// Test hyperlinks
      57             :     void testHyperlinkSearch();
      58             : 
      59             :     void testSectionAttributes();
      60             : 
      61           2 :     CPPUNIT_TEST_SUITE(Test);
      62           1 :     CPPUNIT_TEST(testConstruction);
      63           1 :     CPPUNIT_TEST(testUnoTextFields);
      64           1 :     CPPUNIT_TEST(testAutocorrect);
      65           1 :     CPPUNIT_TEST(testHyperlinkSearch);
      66           1 :     CPPUNIT_TEST(testSectionAttributes);
      67           5 :     CPPUNIT_TEST_SUITE_END();
      68             : 
      69             : private:
      70             :     EditEngineItemPool* mpItemPool;
      71             : };
      72             : 
      73           5 : Test::Test() : mpItemPool(NULL) {}
      74             : 
      75           5 : void Test::setUp()
      76             : {
      77           5 :     test::BootstrapFixture::setUp();
      78             : 
      79           5 :     mpItemPool = new EditEngineItemPool(true);
      80           5 : }
      81             : 
      82           5 : void Test::tearDown()
      83             : {
      84           5 :     SfxItemPool::Free(mpItemPool);
      85           5 :     test::BootstrapFixture::tearDown();
      86           5 : }
      87             : 
      88           1 : void Test::testConstruction()
      89             : {
      90           1 :     EditEngine aEngine(mpItemPool);
      91             : 
      92           2 :     OUString aParaText = "I am Edit Engine.";
      93           2 :     aEngine.SetText(aParaText);
      94           1 : }
      95             : 
      96             : namespace {
      97             : 
      98          14 : bool includes(const uno::Sequence<OUString>& rSeq, const OUString& rVal)
      99             : {
     100          56 :     for (sal_Int32 i = 0, n = rSeq.getLength(); i < n; ++i)
     101          56 :         if (rSeq[i] == rVal)
     102          14 :             return true;
     103             : 
     104           0 :     return false;
     105             : }
     106             : 
     107             : }
     108             : 
     109           1 : void Test::testUnoTextFields()
     110             : {
     111             :     {
     112             :         // DATE
     113           1 :         SvxUnoTextField aField(text::textfield::Type::DATE);
     114           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     115           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
     116           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     117             :     }
     118             : 
     119             :     {
     120             :         // URL
     121           1 :         SvxUnoTextField aField(text::textfield::Type::URL);
     122           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     123           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.URL");
     124           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     125             :     }
     126             : 
     127             :     {
     128             :         // PAGE
     129           1 :         SvxUnoTextField aField(text::textfield::Type::PAGE);
     130           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     131           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageNumber");
     132           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     133             :     }
     134             : 
     135             :     {
     136             :         // PAGES
     137           1 :         SvxUnoTextField aField(text::textfield::Type::PAGES);
     138           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     139           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.PageCount");
     140           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     141             :     }
     142             : 
     143             :     {
     144             :         // TIME
     145           1 :         SvxUnoTextField aField(text::textfield::Type::TIME);
     146           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     147           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
     148           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     149             :     }
     150             : 
     151             :     {
     152             :         // FILE
     153           1 :         SvxUnoTextField aField(text::textfield::Type::DOCINFO_TITLE);
     154           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     155           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.docinfo.Title");
     156           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     157             :     }
     158             : 
     159             :     {
     160             :         // TABLE
     161           1 :         SvxUnoTextField aField(text::textfield::Type::TABLE);
     162           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     163           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.SheetName");
     164           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     165             :     }
     166             : 
     167             :     {
     168             :         // EXTENDED TIME
     169           1 :         SvxUnoTextField aField(text::textfield::Type::EXTENDED_TIME);
     170           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     171           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.DateTime");
     172           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     173             :     }
     174             : 
     175             :     {
     176             :         // EXTENDED FILE
     177           1 :         SvxUnoTextField aField(text::textfield::Type::EXTENDED_FILE);
     178           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     179           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.FileName");
     180           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     181             :     }
     182             : 
     183             :     {
     184             :         // AUTHOR
     185           1 :         SvxUnoTextField aField(text::textfield::Type::AUTHOR);
     186           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     187           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.Author");
     188           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     189             :     }
     190             : 
     191             :     {
     192             :         // MEASURE
     193           1 :         SvxUnoTextField aField(text::textfield::Type::MEASURE);
     194           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     195           1 :         bool bGood = includes(aSvcs, "com.sun.star.text.textfield.Measure");
     196           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     197             :     }
     198             : 
     199             :     {
     200             :         // PRESENTATION HEADER
     201           1 :         SvxUnoTextField aField(text::textfield::Type::PRESENTATION_HEADER);
     202           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     203           1 :         bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.Header");
     204           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     205             :     }
     206             : 
     207             :     {
     208             :         // PRESENTATION FOOTER
     209           1 :         SvxUnoTextField aField(text::textfield::Type::PRESENTATION_FOOTER);
     210           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     211           1 :         bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.Footer");
     212           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     213             :     }
     214             : 
     215             :     {
     216             :         // PRESENTATION DATE TIME
     217           1 :         SvxUnoTextField aField(text::textfield::Type::PRESENTATION_DATE_TIME);
     218           2 :         uno::Sequence<OUString> aSvcs = aField.getSupportedServiceNames();
     219           1 :         bool bGood = includes(aSvcs, "com.sun.star.presentation.textfield.DateTime");
     220           2 :         CPPUNIT_ASSERT_MESSAGE("expected service is not present.", bGood);
     221             :     }
     222           1 : }
     223             : 
     224           3 : class TestAutoCorrDoc : public SvxAutoCorrDoc
     225             : {
     226             : public:
     227             :     /// just like the real thing, this dummy modifies the rText parameter :(
     228           3 :     TestAutoCorrDoc(OUString &rText, LanguageType eLang)
     229             :         : m_rText(rText)
     230           3 :         , m_eLang(eLang)
     231             :     {
     232           3 :     }
     233           3 :     OUString const& getResult() const
     234             :     {
     235           3 :         return m_rText;
     236             :     }
     237             : private:
     238             :     OUString & m_rText;
     239             :     LanguageType m_eLang;
     240           2 :     virtual bool Delete( sal_Int32 nStt, sal_Int32 nEnd ) SAL_OVERRIDE
     241             :     {
     242             :         //fprintf(stderr, "TestAutoCorrDoc::Delete\n");
     243           2 :         m_rText = m_rText.replaceAt(nStt, nEnd-nStt, "");
     244           2 :         return true;
     245             :     }
     246           3 :     virtual bool Insert( sal_Int32 nPos, const OUString& rTxt ) SAL_OVERRIDE
     247             :     {
     248             :         //fprintf(stderr, "TestAutoCorrDoc::Insert\n");
     249           3 :         m_rText = m_rText.replaceAt(nPos, 0, rTxt);
     250           3 :         return true;
     251             :     }
     252           0 :     virtual bool Replace( sal_Int32 nPos, const OUString& rTxt ) SAL_OVERRIDE
     253             :     {
     254             :         //fprintf(stderr, "TestAutoCorrDoc::Replace\n");
     255           0 :         return ReplaceRange( nPos, rTxt.getLength(), rTxt );
     256             :     }
     257           4 :     virtual bool ReplaceRange( sal_Int32 nPos, sal_Int32 nLen, const OUString& rTxt ) SAL_OVERRIDE
     258             :     {
     259             :         //fprintf(stderr, "TestAutoCorrDoc::ReplaceRange %d %d %s\n", nPos, nLen, OUStringToOString(rTxt, RTL_TEXTENCODING_UTF8).getStr());
     260           4 :         m_rText = m_rText.replaceAt(nPos, nLen, rTxt);
     261           4 :         return true;
     262             :     }
     263           1 :     virtual bool SetAttr( sal_Int32, sal_Int32, sal_uInt16, SfxPoolItem& ) SAL_OVERRIDE
     264             :     {
     265             :         //fprintf(stderr, "TestAutoCorrDoc::SetAttr\n");
     266           1 :         return true;
     267             :     }
     268           0 :     virtual bool SetINetAttr( sal_Int32, sal_Int32, const OUString& ) SAL_OVERRIDE
     269             :     {
     270             :         //fprintf(stderr, "TestAutoCorrDoc::SetINetAttr\n");
     271           0 :         return true;
     272             :     }
     273           0 :     virtual OUString const* GetPrevPara(bool) SAL_OVERRIDE
     274             :     {
     275             :         //fprintf(stderr, "TestAutoCorrDoc::GetPrevPara\n");
     276           0 :         return 0;
     277             :     }
     278           2 :     virtual bool ChgAutoCorrWord( sal_Int32& rSttPos,
     279             :                 sal_Int32 nEndPos, SvxAutoCorrect& rACorrect,
     280             :                 OUString* pPara ) SAL_OVERRIDE
     281             :     {
     282             :         //fprintf(stderr, "TestAutoCorrDoc::ChgAutoCorrWord\n");
     283             : 
     284           2 :         if (m_rText.isEmpty())
     285           0 :             return false;
     286             : 
     287           2 :         LanguageTag aLanguageTag( m_eLang);
     288             :         const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
     289           2 :                 m_rText, rSttPos, nEndPos, *this, aLanguageTag);
     290           2 :         if (pFnd && pFnd->IsTextOnly())
     291             :         {
     292           0 :             m_rText = m_rText.replaceAt(rSttPos, nEndPos, pFnd->GetLong());
     293           0 :             if( pPara )
     294           0 :                 pPara->clear(); // =&pCurNode->GetString();
     295           0 :             return true;
     296             :         }
     297             : 
     298           2 :         return false;
     299             :     }
     300             : };
     301             : 
     302             : //https://bugs.libreoffice.org/show_bug.cgi?id=55693
     303             : //Two capitalized letters are not corrected if dash or slash are directly
     304             : //before the two letters
     305           1 : void Test::testAutocorrect()
     306             : {
     307           1 :     OUString sShareAutocorrFile;
     308           2 :     OUString sUserAutocorrFile;
     309           2 :     SvxAutoCorrect aAutoCorrect(sShareAutocorrFile, sUserAutocorrFile);
     310             : 
     311             :     {
     312           1 :         OUString sInput("TEst-TEst");
     313           1 :         sal_Unicode cNextChar(' ');
     314           2 :         OUString sExpected("Test-Test ");
     315             : 
     316           2 :         TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
     317           1 :         aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
     318             : 
     319           2 :         CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected);
     320             :     }
     321             : 
     322             :     {
     323           1 :         OUString sInput("TEst/TEst");
     324           1 :         sal_Unicode cNextChar(' ');
     325           2 :         OUString sExpected("Test/Test ");
     326             : 
     327           2 :         TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
     328           1 :         aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
     329             : 
     330           2 :         CPPUNIT_ASSERT_MESSAGE("autocorrect", aFoo.getResult() == sExpected);
     331             :     }
     332             : 
     333             :     {
     334             :         // test auto-bolding with '*'
     335           1 :         OUString sInput("*foo");
     336           1 :         sal_Unicode cNextChar('*');
     337           2 :         OUString sExpected("foo");
     338             : 
     339           2 :         TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US);
     340           1 :         aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true);
     341             : 
     342           2 :         CPPUNIT_ASSERT_EQUAL(sExpected, aFoo.getResult());
     343           1 :     }
     344           1 : }
     345             : 
     346             : namespace {
     347           1 :     class UrlEditEngine : public EditEngine
     348             :     {
     349             :     public:
     350           1 :         UrlEditEngine(SfxItemPool *pPool) : EditEngine(pPool) {}
     351             : 
     352           1 :         virtual OUString CalcFieldValue( const SvxFieldItem&, sal_Int32, sal_Int32, Color*&, Color*& ) SAL_OVERRIDE
     353             :         {
     354           1 :             return OUString("jim@bob.com"); // a sophisticated view of value:
     355             :         }
     356             :     };
     357             : }
     358             : 
     359             : // Odd accounting for hyperlink position & size etc.
     360             : // https://bugzilla.novell.com/show_bug.cgi?id=467459
     361           1 : void Test::testHyperlinkSearch()
     362             : {
     363           1 :     UrlEditEngine aEngine(mpItemPool);
     364           1 :     EditDoc &rDoc = aEngine.GetEditDoc();
     365             : 
     366           2 :     OUString aSampleText = "Please write email to . if you find a fish(not a dog).";
     367           1 :     aEngine.SetText(aSampleText);
     368             : 
     369           1 :     CPPUNIT_ASSERT_MESSAGE("set text", rDoc.GetParaAsString(sal_Int32(0)) == aSampleText);
     370             : 
     371           1 :     ContentNode *pNode = rDoc.GetObject(0);
     372           1 :     EditSelection aSel(EditPaM(pNode, 22), EditPaM(pNode, 22));
     373             :     SvxURLField aURLField("mailto:///jim@bob.com", "jim@bob.com",
     374           2 :                           SVXURLFORMAT_REPR);
     375           2 :     SvxFieldItem aField(aURLField, EE_FEATURE_FIELD);
     376             : 
     377           1 :     aEngine.InsertField(aSel, aField);
     378           1 :     aEngine.UpdateFields();
     379             : 
     380           2 :     OUString aContent = pNode->GetExpandedText();
     381           2 :     CPPUNIT_ASSERT_MESSAGE("get text", aContent ==
     382           1 :                            "Please write email to jim@bob.com. if you find a fish(not a dog).");
     383           1 :     CPPUNIT_ASSERT_MESSAGE("wrong length", rDoc.GetTextLen() == (sal_uLong)aContent.getLength());
     384             : 
     385             :     // Check expansion and positioning re-work
     386           2 :     CPPUNIT_ASSERT_MESSAGE("wrong length", pNode->GetExpandedLen() ==
     387           1 :                            (sal_uLong)aContent.getLength());
     388          66 :     for (sal_Int32 n = 0; n < aContent.getLength(); n++)
     389             :     {
     390          65 :         sal_Int32 nStart = n, nEnd = n;
     391          65 :         pNode->UnExpandPositions(nStart,nEnd);
     392          65 :         CPPUNIT_ASSERT_MESSAGE("out of bound start", nStart < pNode->Len());
     393          65 :         CPPUNIT_ASSERT_MESSAGE("out of bound end", nEnd <= pNode->Len());
     394             :     }
     395             : 
     396             :     static const struct {
     397             :         sal_Int32 mnStart, mnEnd;
     398             :         sal_Int32 mnNewStart, mnNewEnd;
     399             :     } aTrickyOnes[] = {
     400             :         {  0,  1, /* -> */  0, 1 },
     401             :         { 21, 25, /* -> */ 21, 23 }, // the field is really just one char
     402             :         { 25, 27, /* -> */ 22, 23 },
     403             :         { 50, 56, /* -> */ 40, 46 }
     404             :     };
     405           5 :     for (size_t n = 0; n < SAL_N_ELEMENTS(aTrickyOnes); n++)
     406             :     {
     407           4 :         sal_Int32 nStart = aTrickyOnes[n].mnStart;
     408           4 :         sal_Int32 nEnd = aTrickyOnes[n].mnEnd;
     409           4 :         pNode->UnExpandPositions(nStart,nEnd);
     410             : 
     411           4 :         rtl::OStringBuffer aBuf;
     412           4 :         aBuf = "bound check start is ";
     413           4 :         aBuf.append(nStart).append(" but should be ").append(aTrickyOnes[n].mnNewStart);
     414           4 :         aBuf.append(" in row ").append((sal_Int32)n);
     415           4 :         CPPUNIT_ASSERT_MESSAGE(aBuf.getStr(), nStart == aTrickyOnes[n].mnNewStart);
     416           4 :         aBuf = "bound check end is ";
     417           4 :         aBuf.append(nEnd).append(" but should be ").append(aTrickyOnes[n].mnNewEnd);
     418           4 :         aBuf.append(" in row ").append((sal_Int32)n);
     419           4 :         CPPUNIT_ASSERT_MESSAGE(aBuf.getStr(), nEnd == aTrickyOnes[n].mnNewEnd);
     420           4 :     }
     421             : 
     422           2 :     SvxSearchItem aItem(1); //SID_SEARCH_ITEM);
     423           1 :     aItem.SetBackward(false);
     424           1 :     aItem.SetSelection(false);
     425           1 :     aItem.SetSearchString("fish");
     426           1 :     CPPUNIT_ASSERT_MESSAGE("no fish", aEngine.HasText(aItem));
     427           1 :     aItem.SetSearchString("dog");
     428           2 :     CPPUNIT_ASSERT_MESSAGE("no dog", aEngine.HasText(aItem));
     429           1 : }
     430             : 
     431           5 : bool hasBold(const editeng::Section& rSecAttr)
     432             : {
     433           5 :     std::vector<const SfxPoolItem*>::const_iterator it = rSecAttr.maAttributes.begin(), itEnd = rSecAttr.maAttributes.end();
     434           5 :     for (; it != itEnd; ++it)
     435             :     {
     436           5 :         const SfxPoolItem* p = *it;
     437           5 :         if (p->Which() != EE_CHAR_WEIGHT)
     438           0 :             continue;
     439             : 
     440           5 :         if (static_cast<const SvxWeightItem*>(p)->GetWeight() != WEIGHT_BOLD)
     441           0 :             continue;
     442             : 
     443           5 :         return true;
     444             :     }
     445           0 :     return false;
     446             : }
     447             : 
     448           2 : bool hasItalic(const editeng::Section& rSecAttr)
     449             : {
     450           2 :     std::vector<const SfxPoolItem*>::const_iterator it = rSecAttr.maAttributes.begin(), itEnd = rSecAttr.maAttributes.end();
     451           3 :     for (; it != itEnd; ++it)
     452             :     {
     453           3 :         const SfxPoolItem* p = *it;
     454           3 :         if (p->Which() != EE_CHAR_ITALIC)
     455           1 :             continue;
     456             : 
     457           2 :         if (static_cast<const SvxPostureItem*>(p)->GetPosture() != ITALIC_NORMAL)
     458           0 :             continue;
     459             : 
     460           2 :         return true;
     461             :     }
     462           0 :     return false;
     463             : }
     464             : 
     465           1 : void Test::testSectionAttributes()
     466             : {
     467           1 :     EditEngine aEngine(mpItemPool);
     468             : 
     469           2 :     boost::scoped_ptr<SfxItemSet> pSet(new SfxItemSet(aEngine.GetEmptyItemSet()));
     470           2 :     SvxWeightItem aBold(WEIGHT_BOLD, EE_CHAR_WEIGHT);
     471           2 :     SvxPostureItem aItalic(ITALIC_NORMAL, EE_CHAR_ITALIC);
     472             : 
     473             :     {
     474           1 :         OUString aParaText = "aaabbbccc";
     475           1 :         aEngine.SetText(aParaText);
     476           1 :         pSet->Put(aBold);
     477           1 :         CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
     478           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,6)); // 'aaabbb' - end point is not inclusive.
     479           1 :         pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet()));
     480           1 :         pSet->Put(aItalic);
     481           1 :         CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
     482             : 
     483           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(0,3,0,9)); // 'bbbccc'
     484           2 :         boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject());
     485           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get());
     486           2 :         std::vector<editeng::Section> aAttrs;
     487           1 :         pEditText->GetAllSections(aAttrs);
     488             : 
     489             :         // Now, we should have a total of 3 sections.
     490           1 :         CPPUNIT_ASSERT_MESSAGE("There should be 3 sections.", aAttrs.size() == 3);
     491             : 
     492             :         // First section should be 0-3 of paragraph 0, and it should only have boldness applied.
     493           1 :         const editeng::Section* pSecAttr = &aAttrs[0];
     494           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
     495           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     496           1 :         CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
     497           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
     498           1 :         CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
     499             : 
     500             :         // Second section should be 3-6, and it should be both bold and italic.
     501           1 :         pSecAttr = &aAttrs[1];
     502           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
     503           1 :         CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnStart);
     504           1 :         CPPUNIT_ASSERT_EQUAL(6, (int)pSecAttr->mnEnd);
     505           1 :         CPPUNIT_ASSERT_EQUAL(2, (int)pSecAttr->maAttributes.size());
     506           1 :         CPPUNIT_ASSERT_MESSAGE("This section must be bold and italic.", hasBold(*pSecAttr) && hasItalic(*pSecAttr));
     507             : 
     508             :         // Third section should be 6-9, and it should be only italic.
     509           1 :         pSecAttr = &aAttrs[2];
     510           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
     511           1 :         CPPUNIT_ASSERT_EQUAL(6, (int)pSecAttr->mnStart);
     512           1 :         CPPUNIT_ASSERT_EQUAL(9, (int)pSecAttr->mnEnd);
     513           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
     514           2 :         CPPUNIT_ASSERT_MESSAGE("This section must be italic.", hasItalic(*pSecAttr));
     515             :     }
     516             : 
     517             :     {
     518             :         // Set text consisting of 5 paragraphs with the 2nd and 4th paragraphs
     519             :         // being empty.
     520           1 :         aEngine.Clear();
     521           1 :         aEngine.SetText("one\n\ntwo\n\nthree");
     522           1 :         sal_Int32 nParaCount = aEngine.GetParagraphCount();
     523           1 :         sal_Int32 nCheck = 5;
     524           1 :         CPPUNIT_ASSERT_EQUAL(nCheck, nParaCount);
     525             : 
     526             :         // Apply boldness to paragraphs 1, 3, 5 only. Leave 2 and 4 unformatted.
     527           1 :         pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet()));
     528           1 :         pSet->Put(aBold);
     529           1 :         CPPUNIT_ASSERT_MESSAGE("There should be exactly one item.", pSet->Count() == 1);
     530           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,3));
     531           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(2,0,2,3));
     532           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(4,0,4,5));
     533             : 
     534           1 :         boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject());
     535           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get());
     536           2 :         std::vector<editeng::Section> aAttrs;
     537           1 :         pEditText->GetAllSections(aAttrs);
     538           1 :         size_t nSecCountCheck = 5;
     539           1 :         CPPUNIT_ASSERT_EQUAL(nSecCountCheck, aAttrs.size());
     540             : 
     541             :         // 1st, 3rd and 5th sections should correspond with 1st, 3rd and 5th paragraphs.
     542           1 :         const editeng::Section* pSecAttr = &aAttrs[0];
     543           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
     544           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     545           1 :         CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
     546           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
     547           1 :         CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
     548             : 
     549           1 :         pSecAttr = &aAttrs[2];
     550           1 :         CPPUNIT_ASSERT_EQUAL(2, (int)pSecAttr->mnParagraph);
     551           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     552           1 :         CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnEnd);
     553           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
     554           1 :         CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
     555             : 
     556           1 :         pSecAttr = &aAttrs[4];
     557           1 :         CPPUNIT_ASSERT_EQUAL(4, (int)pSecAttr->mnParagraph);
     558           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     559           1 :         CPPUNIT_ASSERT_EQUAL(5, (int)pSecAttr->mnEnd);
     560           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->maAttributes.size());
     561           1 :         CPPUNIT_ASSERT_MESSAGE("This section must be bold.", hasBold(*pSecAttr));
     562             : 
     563             :         // The 2nd and 4th paragraphs should be empty.
     564           1 :         pSecAttr = &aAttrs[1];
     565           1 :         CPPUNIT_ASSERT_EQUAL(1, (int)pSecAttr->mnParagraph);
     566           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     567           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd);
     568           1 :         CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", pSecAttr->maAttributes.empty());
     569             : 
     570           1 :         pSecAttr = &aAttrs[3];
     571           1 :         CPPUNIT_ASSERT_EQUAL(3, (int)pSecAttr->mnParagraph);
     572           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     573           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd);
     574           2 :         CPPUNIT_ASSERT_MESSAGE("Attribute array should be empty.", pSecAttr->maAttributes.empty());
     575             :     }
     576             : 
     577             : 
     578             :     {
     579           1 :         aEngine.Clear();
     580           1 :         aEngine.SetText("one\ntwo");
     581           1 :         CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), aEngine.GetParagraphCount());
     582             : 
     583             :         // embolden 2nd paragraph
     584           1 :         pSet.reset(new SfxItemSet(aEngine.GetEmptyItemSet()));
     585           1 :         pSet->Put(aBold);
     586           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(1,0,1,3));
     587             :         // disboldify 1st paragraph
     588           1 :         SvxWeightItem aNotSoBold(WEIGHT_NORMAL, EE_CHAR_WEIGHT);
     589           1 :         pSet->Put(aNotSoBold);
     590           1 :         aEngine.QuickSetAttribs(*pSet, ESelection(0,0,0,3));
     591             : 
     592             :         // now delete & join the paragraphs - this is fdo#85496 scenario
     593           1 :         aEngine.QuickDelete(ESelection(0,0,1,3));
     594           1 :         CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), aEngine.GetParagraphCount());
     595             : 
     596           2 :         boost::scoped_ptr<EditTextObject> pEditText(aEngine.CreateTextObject());
     597           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to create text object.", pEditText.get());
     598           2 :         std::vector<editeng::Section> aAttrs;
     599           1 :         pEditText->GetAllSections(aAttrs);
     600             : 
     601           1 :         CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aAttrs.size());
     602             : 
     603           1 :         const editeng::Section* pSecAttr = &aAttrs[0];
     604           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnParagraph);
     605           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnStart);
     606           1 :         CPPUNIT_ASSERT_EQUAL(0, (int)pSecAttr->mnEnd);
     607           2 :         std::set<sal_uInt16> whiches;
     608           2 :         for (size_t i = 0; i < pSecAttr->maAttributes.size(); ++i)
     609             :         {
     610           1 :             sal_uInt16 const nWhich(pSecAttr->maAttributes[i]->Which());
     611           2 :             CPPUNIT_ASSERT_MESSAGE("duplicate item in text portion attributes",
     612           1 :                 whiches.insert(nWhich).second);
     613           1 :         }
     614           1 :     }
     615           1 : }
     616             : 
     617           1 : CPPUNIT_TEST_SUITE_REGISTRATION(Test);
     618             : 
     619             : }
     620             : 
     621           4 : CPPUNIT_PLUGIN_IMPLEMENT();
     622             : 
     623             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11