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 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;
|
||||
};
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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: */
|
||||
|
Reference in New Issue
Block a user