[Libreoffice-commits] core.git: sw/inc sw/qa sw/source

Tobias Lippert drtl at fastmail.fm
Fri Jun 6 05:19:36 PDT 2014


 sw/inc/ToxTextGenerator.hxx                 |   26 +++++
 sw/inc/chpfld.hxx                           |    4 
 sw/qa/cppunit/tox/test_ToxTextGenerator.cxx |   92 +++++++++++++++++++
 sw/source/core/tox/ToxTextGenerator.cxx     |  129 ++++++++++++++++++----------
 4 files changed, 204 insertions(+), 47 deletions(-)

New commits:
commit 0a1b1511faaa3302429d93ccdad3eb41dc8f36cb
Author: Tobias Lippert <drtl at fastmail.fm>
Date:   Sun Jun 1 14:24:51 2014 +0200

    Unittest generation of text for chapter entries in the TOC
    
    Conflicts:
    	sw/inc/ToxTextGenerator.hxx
    	sw/qa/cppunit/tox/test_ToxTextGenerator.cxx
    	sw/source/core/tox/ToxTextGenerator.cxx
    
    Change-Id: I343958f85fb6718215a0caa456a825d72f168a57
    Reviewed-on: https://gerrit.libreoffice.org/9612
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/inc/ToxTextGenerator.hxx b/sw/inc/ToxTextGenerator.hxx
index ba79177..fa52fba 100644
--- a/sw/inc/ToxTextGenerator.hxx
+++ b/sw/inc/ToxTextGenerator.hxx
@@ -30,8 +30,13 @@
 class SfxItemSet;
 class SwAttrPool;
 class SwFmtAutoFmt;
+class SwChapterField;
+class SwChapterFieldType;
+class SwCntntFrm;
+class SwCntntNode;
 class SwDoc;
 class SwForm;
+class SwFormToken;
 class SwPageDesc;
 class SwTxtAttr;
 class SwTxtNode;
@@ -47,7 +52,7 @@ class SW_DLLPUBLIC ToxTextGenerator
 public:
     ToxTextGenerator(const SwForm& toxForm);
 
-    ~ToxTextGenerator();
+    virtual ~ToxTextGenerator();
 
     /** Generate the text for an entry of a table of X (X is, e.g., content).
      *
@@ -118,6 +123,25 @@ private:
     static OUString
     GetNumStringOfFirstNode(const SwTOXSortTabBase& rBase, bool bUsePrefix, sal_uInt8 nLevel);
 
+    /** Handle a chapter token.
+     */
+    OUString
+    HandleChapterToken(const SwTOXSortTabBase& rBase, const SwFormToken& aToken, SwDoc* pDoc) const;
+
+    /** Generate the text for a chapter token.
+     */
+    OUString
+    GenerateTextForChapterToken(const SwFormToken& chapterToken, const SwCntntFrm* contentFrame,
+            const SwCntntNode *contentNode) const;
+
+    /** Obtain a ChapterField to use for the text generation.
+     * @internal
+     * This method is overridden in the unittests. Do not override it yourself.
+     */
+    virtual SwChapterField
+    ObtainChapterField(SwChapterFieldType* chapterFieldType, const SwFormToken* chapterToken,
+            const SwCntntFrm* contentFrame, const SwCntntNode *contentNode) const;
+
     friend class ::ToxTextGeneratorTest;
 };
 
diff --git a/sw/inc/chpfld.hxx b/sw/inc/chpfld.hxx
index 452c42c..dc59de1 100644
--- a/sw/inc/chpfld.hxx
+++ b/sw/inc/chpfld.hxx
@@ -24,6 +24,7 @@
 class SwFrm;
 class SwCntntNode;
 class SwTxtNode;
+class ToxTextGeneratorTest;
 
 enum SwChapterFormat
 {
@@ -36,7 +37,7 @@ enum SwChapterFormat
     CF_END
 };
 
-class SwChapterFieldType : public SwFieldType
+class SW_DLLPUBLIC SwChapterFieldType : public SwFieldType
 {
 public:
     SwChapterFieldType();
@@ -48,6 +49,7 @@ public:
 class SW_DLLPUBLIC SwChapterField : public SwField
 {
     friend class SwChapterFieldType;
+    friend class ToxTextGeneratorTest; // the unittest needs to mock the chapter fields.
     sal_uInt8 nLevel;
     OUString sTitle;
     OUString sNumber;
diff --git a/sw/qa/cppunit/tox/test_ToxTextGenerator.cxx b/sw/qa/cppunit/tox/test_ToxTextGenerator.cxx
index c2e1dcb..7ef8506 100644
--- a/sw/qa/cppunit/tox/test_ToxTextGenerator.cxx
+++ b/sw/qa/cppunit/tox/test_ToxTextGenerator.cxx
@@ -8,6 +8,7 @@
  */
 
 #include "rtl/ustring.hxx"
+#include "chpfld.hxx"
 #include "tox.hxx"
 #include "txmsrt.hxx"
 #include "ToxTextGenerator.hxx"
@@ -25,12 +26,18 @@ public:
     void OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem();
     void TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem();
     void EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet();
+    void EmptyStringIsReturnedAsNumStringIfToxSourcesIsEmpty();
+    void ChapterNumberWithoutTextIsGeneratedForNoprepstTitle();
+    void ChapterNumberWithTitleIsGeneratedForNumberNoPrepst();
 
     CPPUNIT_TEST_SUITE(ToxTextGeneratorTest);
     CPPUNIT_TEST(EmptyStringIsReturnedForPageNumberPlaceholderOfZeroItems);
     CPPUNIT_TEST(OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem);
     CPPUNIT_TEST(TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem);
     CPPUNIT_TEST(EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet);
+    CPPUNIT_TEST(EmptyStringIsReturnedAsNumStringIfToxSourcesIsEmpty);
+    CPPUNIT_TEST(ChapterNumberWithoutTextIsGeneratedForNoprepstTitle);
+    CPPUNIT_TEST(ChapterNumberWithTitleIsGeneratedForNumberNoPrepst);
     CPPUNIT_TEST_SUITE_END();
 
 };
@@ -82,6 +89,91 @@ ToxTextGeneratorTest::EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet()
     CPPUNIT_ASSERT_EQUAL(expected, actual);
 }
 
+void
+ToxTextGeneratorTest::EmptyStringIsReturnedAsNumStringIfToxSourcesIsEmpty()
+{
+    MockedSortTab sortTab;
+    sortTab.pTxtMark = reinterpret_cast<SwTxtTOXMark*>(1);
+
+    OUString expected("");
+    OUString actual = ToxTextGenerator::GetNumStringOfFirstNode(sortTab, false, 0);
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+}
+
+class ToxTextGeneratorWithMockedChapterField : public ToxTextGenerator {
+public:
+    ToxTextGeneratorWithMockedChapterField(SwForm &form)
+    : ToxTextGenerator(form), mChapterFieldType(), mChapterField(&mChapterFieldType) {;}
+
+    SwChapterField&
+    GetChapterField() {
+        return mChapterField;
+    }
+
+private:
+    SwChapterField
+    ObtainChapterField(SwChapterFieldType* chapterFieldType, const SwFormToken* chapterToken,
+            const SwCntntFrm* contentFrame, const SwCntntNode *contentNode) const {
+        // get rid of 'unused-parameters' warnings
+        (void)(chapterFieldType);(void)(chapterToken);(void)(contentFrame);(void)(contentNode);
+        return mChapterField;
+    }
+
+    SwChapterFieldType mChapterFieldType;
+    SwChapterField mChapterField;
+};
+
+void
+ToxTextGeneratorTest::ChapterNumberWithoutTextIsGeneratedForNoprepstTitle()
+{
+    SwForm form;
+    ToxTextGeneratorWithMockedChapterField ttg(form);
+    // set all values to make sure they are not used
+    ttg.GetChapterField().sNumber = "1";
+    ttg.GetChapterField().sPre = "PRE";
+    ttg.GetChapterField().sPost = "POST";
+    ttg.GetChapterField().sTitle = "TITLE";
+
+    SwFormToken token(TOKEN_CHAPTER_INFO);
+    token.nChapterFormat = CF_NUM_NOPREPST_TITLE;
+
+    OUString expected("1");
+    OUString actual = ttg.GenerateTextForChapterToken(token, NULL, NULL);
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+
+    // we cannot mock the pre- and suffix generation in the chapterfield. We just test that sNumber and
+    // sTitle are used and hope that the pre- and suffix addition works.
+    token.nChapterFormat = CF_NUMBER;
+    expected = ttg.GenerateTextForChapterToken(token, NULL, NULL);
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+}
+
+
+void
+ToxTextGeneratorTest::ChapterNumberWithTitleIsGeneratedForNumberNoPrepst()
+{
+    SwForm form;
+    ToxTextGeneratorWithMockedChapterField ttg(form);
+    // set all values to make sure they are not used
+    ttg.GetChapterField().sNumber = "5";
+    ttg.GetChapterField().sPre = "PRE";
+    ttg.GetChapterField().sPost = "POST";
+    ttg.GetChapterField().sTitle = "myTitle";
+
+    SwFormToken token(TOKEN_CHAPTER_INFO);
+    token.nChapterFormat = CF_NUMBER_NOPREPST;
+
+    OUString expected("5 myTitle");
+    OUString actual = ttg.GenerateTextForChapterToken(token, NULL, NULL);
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+
+    // we cannot mock the pre- and suffix generation in the chapterfield. We just test that sNumber and
+    // sTitle are used and hope that the pre- and suffix addition works.
+    token.nChapterFormat = CF_NUM_TITLE;
+    expected = ttg.GenerateTextForChapterToken(token, NULL, NULL);
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+}
+
 // Put the test suite in the registry
 CPPUNIT_TEST_SUITE_REGISTRATION(ToxTextGeneratorTest);
 
diff --git a/sw/source/core/tox/ToxTextGenerator.cxx b/sw/source/core/tox/ToxTextGenerator.cxx
index 1360f6d..67de2cd 100644
--- a/sw/source/core/tox/ToxTextGenerator.cxx
+++ b/sw/source/core/tox/ToxTextGenerator.cxx
@@ -46,18 +46,34 @@
 
 #include <boost/foreach.hpp>
 #include <boost/make_shared.hpp>
+#include <cassert>
+
+namespace {
+
+bool sortTabHasNoToxSourcesOrFirstToxSourceHasNoNode(const SwTOXSortTabBase& sortTab)
+{
+    if (sortTab.aTOXSources.empty()) {
+        return true;
+    }
+    if (sortTab.aTOXSources.at(0).pNd != NULL) {
+        return true;
+    }
+    return false;
+}
+
+} // end anonymous namespace
 
 namespace sw {
 
 OUString
 ToxTextGenerator::GetNumStringOfFirstNode( const SwTOXSortTabBase& rBase, bool bUsePrefix, sal_uInt8 nLevel )
 {
-    OUString sRet;
-    if (!rBase.pTxtMark) { // only if it's not a Mark
-        return sRet;
+    if (sortTabHasNoToxSourcesOrFirstToxSourceHasNoNode(rBase)) {
+        return OUString();
     }
 
-    if (rBase.aTOXSources.empty()) {
+    OUString sRet;
+    if (!rBase.pTxtMark) { // only if it's not a Mark
         return sRet;
     }
 
@@ -87,6 +103,54 @@ ToxTextGenerator::ToxTextGenerator(const SwForm& toxForm)
 ToxTextGenerator::~ToxTextGenerator()
 {;}
 
+OUString
+ToxTextGenerator::HandleChapterToken(const SwTOXSortTabBase& rBase, const SwFormToken& aToken,
+        SwDoc* pDoc) const
+{
+    if (sortTabHasNoToxSourcesOrFirstToxSourceHasNoNode(rBase)) {
+        return OUString();
+    }
+
+    // A bit tricky: Find a random Frame
+    const SwCntntNode* contentNode = rBase.aTOXSources.at(0).pNd->GetCntntNode();
+    if (!contentNode) {
+        return OUString();
+    }
+
+    // #i53420#
+    const SwCntntFrm* contentFrame = contentNode->getLayoutFrm(pDoc->GetCurrentLayout());
+    if (!contentFrame) {
+        return OUString();
+    }
+
+    return GenerateTextForChapterToken(aToken, contentFrame, contentNode);
+}
+
+OUString
+ToxTextGenerator::GenerateTextForChapterToken(const SwFormToken& chapterToken, const SwCntntFrm* contentFrame,
+        const SwCntntNode *contentNode) const
+{
+    OUString retval;
+
+    SwChapterFieldType chapterFieldType;
+    SwChapterField aFld = ObtainChapterField(&chapterFieldType, &chapterToken, contentFrame, contentNode);
+
+    //---> #i89791#
+    // continue to support CF_NUMBER and CF_NUM_TITLE in order to handle ODF 1.0/1.1 written by OOo 3.x
+    // in the same way as OOo 2.x would handle them.
+    if (CF_NUM_NOPREPST_TITLE == chapterToken.nChapterFormat || CF_NUMBER == chapterToken.nChapterFormat) {
+        retval += aFld.GetNumber(); // get the string number without pre/postfix
+    }
+    else if (CF_NUMBER_NOPREPST == chapterToken.nChapterFormat || CF_NUM_TITLE == chapterToken.nChapterFormat) {
+        retval += aFld.GetNumber();
+        retval += " ";
+        retval += aFld.GetTitle();
+    } else if (CF_TITLE == chapterToken.nChapterFormat) {
+        retval += aFld.GetTitle();
+    }
+    return retval;
+}
+
 // Add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> in order to control,
 // which page description is used, no appropriate one is found.
 void ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<SwTOXSortTabBase*> &entries,
@@ -224,46 +288,7 @@ void ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<SwTOXSortTabB
                 break;
 
             case TOKEN_CHAPTER_INFO:
-                {
-                    // A bit tricky: Find a random Frame
-                    const SwTOXSource* pTOXSource = 0;
-                    if (!rBase.aTOXSources.empty())
-                        pTOXSource = &rBase.aTOXSources[0];
-
-                    // #i53420#
-                    if ( pTOXSource && pTOXSource->pNd &&
-                         pTOXSource->pNd->IsCntntNode() )
-                    {
-                        const SwCntntFrm* pFrm = pTOXSource->pNd->getLayoutFrm( pDoc->GetCurrentLayout() );
-                        if( pFrm )
-                        {
-                            SwChapterFieldType aFldTyp;
-                            SwChapterField aFld( &aFldTyp, aToken.nChapterFormat );
-                            aFld.SetLevel( static_cast<sal_uInt8>(aToken.nOutlineLevel - 1) );
-                            // #i53420#
-                            aFld.ChangeExpansion( pFrm,
-                                dynamic_cast<const SwCntntNode*>(pTOXSource->pNd),
-                                true );
-                            //---> #i89791#
-                            // continue to support CF_NUMBER
-                            // and CF_NUM_TITLE in order to handle ODF 1.0/1.1
-                            // written by OOo 3.x in the same way as OOo 2.x
-                            // would handle them.
-                            if ( CF_NUM_NOPREPST_TITLE == aToken.nChapterFormat ||
-                                 CF_NUMBER == aToken.nChapterFormat )
-                                rTxt += aFld.GetNumber(); // get the string number without pre/postfix
-                            else if ( CF_NUMBER_NOPREPST == aToken.nChapterFormat ||
-                                      CF_NUM_TITLE == aToken.nChapterFormat )
-                            {
-                                rTxt += aFld.GetNumber();
-                                rTxt += " ";
-                                rTxt += aFld.GetTitle();
-                            }
-                            else if(CF_TITLE == aToken.nChapterFormat)
-                                rTxt += aFld.GetTitle();
-                        }
-                    }
-                }
+                rTxt += HandleChapterToken(rBase, aToken, pDoc);
                 break;
 
             case TOKEN_LINK_START:
@@ -375,7 +400,7 @@ ToxTextGenerator::ApplyHandledTextToken(const HandledTextToken& htt, SwTxtNode&
     }
 }
 
-OUString
+/*static*/ OUString
 ToxTextGenerator::ConstructPageNumberPlaceholder(size_t numberOfToxSources)
 {
     OUString retval;
@@ -392,6 +417,20 @@ ToxTextGenerator::ConstructPageNumberPlaceholder(size_t numberOfToxSources)
     return retval;
 }
 
+/*virtual*/ SwChapterField
+ToxTextGenerator::ObtainChapterField(SwChapterFieldType* chapterFieldType,
+        const SwFormToken* chapterToken, const SwCntntFrm* contentFrame,
+        const SwCntntNode* contentNode) const
+{
+    assert(chapterToken);
+    assert(chapterToken->nOutlineLevel >= 1);
+
+    SwChapterField retval(chapterFieldType, chapterToken->nChapterFormat);
+    retval.SetLevel(static_cast<sal_uInt8>(chapterToken->nOutlineLevel - 1));
+    // #i53420#
+    retval.ChangeExpansion(contentFrame, contentNode, true);
+    return retval;
+}
 } // end namespace sw
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list