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@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
This commit is contained in:
committed by
Caolán McNamara
parent
1534c33633
commit
0a1b1511fa
@@ -30,8 +30,13 @@
|
|||||||
class SfxItemSet;
|
class SfxItemSet;
|
||||||
class SwAttrPool;
|
class SwAttrPool;
|
||||||
class SwFmtAutoFmt;
|
class SwFmtAutoFmt;
|
||||||
|
class SwChapterField;
|
||||||
|
class SwChapterFieldType;
|
||||||
|
class SwCntntFrm;
|
||||||
|
class SwCntntNode;
|
||||||
class SwDoc;
|
class SwDoc;
|
||||||
class SwForm;
|
class SwForm;
|
||||||
|
class SwFormToken;
|
||||||
class SwPageDesc;
|
class SwPageDesc;
|
||||||
class SwTxtAttr;
|
class SwTxtAttr;
|
||||||
class SwTxtNode;
|
class SwTxtNode;
|
||||||
@@ -47,7 +52,7 @@ class SW_DLLPUBLIC ToxTextGenerator
|
|||||||
public:
|
public:
|
||||||
ToxTextGenerator(const SwForm& toxForm);
|
ToxTextGenerator(const SwForm& toxForm);
|
||||||
|
|
||||||
~ToxTextGenerator();
|
virtual ~ToxTextGenerator();
|
||||||
|
|
||||||
/** Generate the text for an entry of a table of X (X is, e.g., content).
|
/** Generate the text for an entry of a table of X (X is, e.g., content).
|
||||||
*
|
*
|
||||||
@@ -118,6 +123,25 @@ private:
|
|||||||
static OUString
|
static OUString
|
||||||
GetNumStringOfFirstNode(const SwTOXSortTabBase& rBase, bool bUsePrefix, sal_uInt8 nLevel);
|
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;
|
friend class ::ToxTextGeneratorTest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
class SwFrm;
|
class SwFrm;
|
||||||
class SwCntntNode;
|
class SwCntntNode;
|
||||||
class SwTxtNode;
|
class SwTxtNode;
|
||||||
|
class ToxTextGeneratorTest;
|
||||||
|
|
||||||
enum SwChapterFormat
|
enum SwChapterFormat
|
||||||
{
|
{
|
||||||
@@ -36,7 +37,7 @@ enum SwChapterFormat
|
|||||||
CF_END
|
CF_END
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwChapterFieldType : public SwFieldType
|
class SW_DLLPUBLIC SwChapterFieldType : public SwFieldType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SwChapterFieldType();
|
SwChapterFieldType();
|
||||||
@@ -48,6 +49,7 @@ public:
|
|||||||
class SW_DLLPUBLIC SwChapterField : public SwField
|
class SW_DLLPUBLIC SwChapterField : public SwField
|
||||||
{
|
{
|
||||||
friend class SwChapterFieldType;
|
friend class SwChapterFieldType;
|
||||||
|
friend class ToxTextGeneratorTest; // the unittest needs to mock the chapter fields.
|
||||||
sal_uInt8 nLevel;
|
sal_uInt8 nLevel;
|
||||||
OUString sTitle;
|
OUString sTitle;
|
||||||
OUString sNumber;
|
OUString sNumber;
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rtl/ustring.hxx"
|
#include "rtl/ustring.hxx"
|
||||||
|
#include "chpfld.hxx"
|
||||||
#include "tox.hxx"
|
#include "tox.hxx"
|
||||||
#include "txmsrt.hxx"
|
#include "txmsrt.hxx"
|
||||||
#include "ToxTextGenerator.hxx"
|
#include "ToxTextGenerator.hxx"
|
||||||
@@ -25,12 +26,18 @@ public:
|
|||||||
void OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem();
|
void OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem();
|
||||||
void TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem();
|
void TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem();
|
||||||
void EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet();
|
void EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet();
|
||||||
|
void EmptyStringIsReturnedAsNumStringIfToxSourcesIsEmpty();
|
||||||
|
void ChapterNumberWithoutTextIsGeneratedForNoprepstTitle();
|
||||||
|
void ChapterNumberWithTitleIsGeneratedForNumberNoPrepst();
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(ToxTextGeneratorTest);
|
CPPUNIT_TEST_SUITE(ToxTextGeneratorTest);
|
||||||
CPPUNIT_TEST(EmptyStringIsReturnedForPageNumberPlaceholderOfZeroItems);
|
CPPUNIT_TEST(EmptyStringIsReturnedForPageNumberPlaceholderOfZeroItems);
|
||||||
CPPUNIT_TEST(OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem);
|
CPPUNIT_TEST(OneAtSignIsReturnedForPageNumberPlaceholderOfOneItem);
|
||||||
CPPUNIT_TEST(TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem);
|
CPPUNIT_TEST(TwoAtSignsAreReturnedForPageNumberPlaceholderOfOneItem);
|
||||||
CPPUNIT_TEST(EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet);
|
CPPUNIT_TEST(EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet);
|
||||||
|
CPPUNIT_TEST(EmptyStringIsReturnedAsNumStringIfToxSourcesIsEmpty);
|
||||||
|
CPPUNIT_TEST(ChapterNumberWithoutTextIsGeneratedForNoprepstTitle);
|
||||||
|
CPPUNIT_TEST(ChapterNumberWithTitleIsGeneratedForNumberNoPrepst);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -82,6 +89,91 @@ ToxTextGeneratorTest::EmptyStringIsReturnedAsNumStringIfNoTextMarkIsSet()
|
|||||||
CPPUNIT_ASSERT_EQUAL(expected, actual);
|
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
|
// Put the test suite in the registry
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(ToxTextGeneratorTest);
|
CPPUNIT_TEST_SUITE_REGISTRATION(ToxTextGeneratorTest);
|
||||||
|
|
||||||
|
@@ -46,18 +46,34 @@
|
|||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/make_shared.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 {
|
namespace sw {
|
||||||
|
|
||||||
OUString
|
OUString
|
||||||
ToxTextGenerator::GetNumStringOfFirstNode( const SwTOXSortTabBase& rBase, bool bUsePrefix, sal_uInt8 nLevel )
|
ToxTextGenerator::GetNumStringOfFirstNode( const SwTOXSortTabBase& rBase, bool bUsePrefix, sal_uInt8 nLevel )
|
||||||
{
|
{
|
||||||
OUString sRet;
|
if (sortTabHasNoToxSourcesOrFirstToxSourceHasNoNode(rBase)) {
|
||||||
if (!rBase.pTxtMark) { // only if it's not a Mark
|
return OUString();
|
||||||
return sRet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rBase.aTOXSources.empty()) {
|
OUString sRet;
|
||||||
|
if (!rBase.pTxtMark) { // only if it's not a Mark
|
||||||
return sRet;
|
return sRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +103,54 @@ ToxTextGenerator::ToxTextGenerator(const SwForm& toxForm)
|
|||||||
ToxTextGenerator::~ToxTextGenerator()
|
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,
|
// Add parameter <_TOXSectNdIdx> and <_pDefaultPageDesc> in order to control,
|
||||||
// which page description is used, no appropriate one is found.
|
// which page description is used, no appropriate one is found.
|
||||||
void ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<SwTOXSortTabBase*> &entries,
|
void ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<SwTOXSortTabBase*> &entries,
|
||||||
@@ -224,46 +288,7 @@ void ToxTextGenerator::GenerateText(SwDoc* pDoc, const std::vector<SwTOXSortTabB
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKEN_CHAPTER_INFO:
|
case TOKEN_CHAPTER_INFO:
|
||||||
{
|
rTxt += HandleChapterToken(rBase, aToken, pDoc);
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKEN_LINK_START:
|
case TOKEN_LINK_START:
|
||||||
@@ -375,7 +400,7 @@ ToxTextGenerator::ApplyHandledTextToken(const HandledTextToken& htt, SwTxtNode&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString
|
/*static*/ OUString
|
||||||
ToxTextGenerator::ConstructPageNumberPlaceholder(size_t numberOfToxSources)
|
ToxTextGenerator::ConstructPageNumberPlaceholder(size_t numberOfToxSources)
|
||||||
{
|
{
|
||||||
OUString retval;
|
OUString retval;
|
||||||
@@ -392,6 +417,20 @@ ToxTextGenerator::ConstructPageNumberPlaceholder(size_t numberOfToxSources)
|
|||||||
return retval;
|
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
|
} // end namespace sw
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
Reference in New Issue
Block a user