From d10f6d49b77dcf955629901937d8d5e3a2976a6c Mon Sep 17 00:00:00 2001 From: Jan-Marek Glogowski Date: Tue, 23 Sep 2014 10:00:13 +0200 Subject: MM: first unit test and infrastructure Extendes SwModelTestBase with mail merge functions and a declaration of the DECLARE_MAILMERGE_TEST macro and uses it in a first test. As most tests it's registered as a slow test run by 'make check'. The broken MM used to drop the leading empty pages, which resulted in a document with 4 pages and the two page bound draws merged per single page. Tests the MM result for page count (eight) and each draw anchor to be on a different page. Change-Id: Iab17f5844e68221d48cb89863323bcfe4c8ae0d2 --- sw/CppunitTest_sw_mailmerge.mk | 93 ++++++++++++ sw/Module_sw.mk | 1 + sw/qa/extras/inc/swmodeltestbase.hxx | 161 ++++++++++++++++++++- sw/qa/extras/mailmerge/data/4_v01.ods | Bin 0 -> 18847 bytes .../data/multiple-page-anchored-draws.odt | Bin 0 -> 9257 bytes sw/qa/extras/mailmerge/mailmerge.cxx | 76 ++++++++++ 6 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 sw/CppunitTest_sw_mailmerge.mk create mode 100644 sw/qa/extras/mailmerge/data/4_v01.ods create mode 100644 sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odt create mode 100644 sw/qa/extras/mailmerge/mailmerge.cxx diff --git a/sw/CppunitTest_sw_mailmerge.mk b/sw/CppunitTest_sw_mailmerge.mk new file mode 100644 index 000000000000..f1020ff09b17 --- /dev/null +++ b/sw/CppunitTest_sw_mailmerge.mk @@ -0,0 +1,93 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,sw_mailmerge)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sw_mailmerge, \ + sw/qa/extras/mailmerge/mailmerge \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sw_mailmerge, \ + comphelper \ + cppu \ + sal \ + sw \ + test \ + unotest \ + utl \ +)) + +$(eval $(call gb_CppunitTest_use_externals,sw_mailmerge, \ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_use_api,sw_mailmerge,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_CppunitTest_use_components,sw_mailmerge, \ + basic/util/sb \ + comphelper/util/comphelp \ + configmgr/source/configmgr \ + connectivity/source/cpool/dbpool2 \ + connectivity/source/drivers/calc/calc \ + connectivity/source/manager/sdbc2 \ + dbaccess/source/filter/xml/dbaxml \ + dbaccess/util/dba \ + embeddedobj/util/embobj \ + filter/source/config/cache/filterconfig1 \ + filter/source/storagefilterdetect/storagefd \ + forms/util/frm \ + framework/util/fwk \ + i18npool/util/i18npool \ + lingucomponent/source/languageguessing/guesslang \ + linguistic/source/lng \ + oox/util/oox \ + package/source/xstor/xstor \ + package/util/package2 \ + sax/source/expatwrap/expwrap \ + sc/util/sc \ + sfx2/util/sfx \ + sot/util/sot \ + svl/source/fsstor/fsstorage \ + svl/util/svl \ + svtools/util/svt \ + sw/util/sw \ + sw/util/swd \ + toolkit/util/tk \ + ucb/source/core/ucb1 \ + ucb/source/ucp/file/ucpfile1 \ + ucb/source/ucp/tdoc/ucptdoc1 \ + unotools/util/utl \ + unoxml/source/rdf/unordf \ + unoxml/source/service/unoxml \ + uui/util/uui \ + $(if $(filter-out MACOSX WNT,$(OS)), \ + $(if $(ENABLE_HEADLESS),, \ + vcl/vcl.unx \ + ) \ + ) \ + xmloff/util/xo \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sw_mailmerge)) +$(eval $(call gb_CppunitTest_use_ure,sw_mailmerge)) +$(eval $(call gb_CppunitTest_use_vcl,sw_mailmerge)) + +$(eval $(call gb_CppunitTest_set_include,sw_mailmerge,\ + -I$(SRCDIR)/sw/inc \ + -I$(SRCDIR)/sw/source/core/inc \ + -I$(SRCDIR)/sw/qa/extras/inc \ + -I$(SRCDIR)/sw/source/uibase/inc \ + $$(INCLUDE) \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index 3a3d75b6b17c..ba58d73bba52 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -71,6 +71,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_odfexport \ CppunitTest_sw_odfimport \ CppunitTest_sw_uiwriter \ + CppunitTest_sw_mailmerge \ )) ifneq ($(DISABLE_CVE_TESTS),TRUE) diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 154d18c918b2..cb2b2b9cd263 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -23,6 +23,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -34,6 +39,8 @@ #include #include #include +#include +#include #include #include @@ -135,6 +142,29 @@ using namespace css; CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \ void TestName::verify() +#define DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, BaseClass) \ + class TestName : public BaseClass { \ + protected: \ + virtual OUString getTestName() SAL_OVERRIDE { return OUString::createFromAscii(#TestName); } \ + public: \ + CPPUNIT_TEST_SUITE(TestName); \ + CPPUNIT_TEST(MailMerge); \ + CPPUNIT_TEST_SUITE_END(); \ + \ + void MailMerge() { \ + executeMailMergeTest(filename, datasource, tablename); \ + } \ + void verify() SAL_OVERRIDE; \ + }; \ + CPPUNIT_TEST_SUITE_REGISTRATION(TestName); \ + void TestName::verify() + +/** + * Maps database URIs to the registered database names for quick lookups + */ +typedef std::map DBuriMap; +DBuriMap aDBuriMap; + /// Base class for filter tests loading or roundtriping a document, then asserting the document model. class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools { @@ -142,7 +172,11 @@ private: OUString maFilterOptions; protected: - uno::Reference mxComponent; + uno::Reference< lang::XComponent > mxComponent; + uno::Reference< lang::XComponent > mxMMComponent; + uno::Reference< com::sun::star::task::XJob > mxJob; + uno::Sequence< beans::NamedValue > mSeqMailMergeArgs; + xmlBufferPtr mpXmlBuffer; const char* mpTestDocumentPath; const char* mpFilter; @@ -156,7 +190,9 @@ protected: sal_uInt32 mnStartTime; utl::TempFile maTempFile; + utl::TempFile maTempDir; bool mbExported; ///< Does maTempFile already contain something useful? + sal_Int16 nCurOutputType; protected: virtual OUString getTestName() { return OUString(); } @@ -176,7 +212,9 @@ public: , mpTestDocumentPath(pTestDocumentPath) , mpFilter(pFilter) , mnStartTime(0) + , maTempDir(NULL, true) , mbExported(false) + , nCurOutputType(0) { maTempFile.EnableKillingFile(); } @@ -195,6 +233,16 @@ public: { if (mxComponent.is()) mxComponent->dispose(); + if (mxMMComponent.is()) + { + if (nCurOutputType == text::MailMergeType::SHELL) + { + SwXTextDocument* pTxtDoc = dynamic_cast(mxMMComponent.get()); + pTxtDoc->GetDocShell()->DoClose(); + } + else + mxMMComponent->dispose(); + } test::BootstrapFixture::tearDown(); } @@ -258,6 +306,32 @@ protected: maTempFile.EnableKillingFile(); } + /** + * Helper func used by each unit test to test the 'mail merge' code. + * + * Registers the data source, loads the original file as reference, + * initializes the mail merge job and its default argument sequence. + * + * The 'verify' method actually has to execute the mail merge by + * calling executeMailMerge() after modifying the job arguments. + */ + void executeMailMergeTest(const char* filename, const char* datasource, const char* tablename = 0) + { + header(); + preTest(filename); + load(mpTestDocumentPath, filename); + + const OUString aPrefix( "LOMM_" ); + const OUString aWorkDir = maTempDir.GetURL(); + const OUString aURI( getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(datasource) ); + OUString aDBName = registerDBsource( aURI, aPrefix, aWorkDir ); + initMailMergeJobAndArgs( filename, tablename, aDBName, aPrefix, aWorkDir ); + + postTest(filename); + verify(); + finish(); + } + /** * Function overloaded by unit test. See DECLARE_SW_*_TEST macros */ @@ -288,7 +362,7 @@ protected: } /** - * Override this function if not calcing layout is needed + * Override this function if calcing layout is not needed */ virtual bool mustCalcLayoutOf(const char* /*filename*/) { @@ -688,6 +762,89 @@ protected: xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"), BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("o"), BAD_CAST("urn:schemas-microsoft-com:office:office")); } + + virtual OUString registerDBsource( const OUString &aURI, const OUString &aPrefix, const OUString &aWorkDir ) + { + OUString aDBName; + DBuriMap::const_iterator pos = aDBuriMap.find( aURI ); + if (pos == aDBuriMap.end()) + { + aDBName = SwDBManager::LoadAndRegisterDataSource( aURI, &aPrefix, &aWorkDir ); + aDBuriMap.insert( std::pair< OUString, OUString >( aURI, aDBName ) ); + std::cout << "New datasource name: '" << aDBName << "'" << std::endl; + } + else + { + aDBName = pos->second; + std::cout << "Old datasource name: '" << aDBName << "'" << std::endl; + } + CPPUNIT_ASSERT(!aDBName.isEmpty()); + return aDBName; + } + + virtual void initMailMergeJobAndArgs( const char* filename, const char* tablename, const OUString &aDBName, + const OUString &aPrefix, const OUString &aWorkDir ) + { + uno::Reference< task::XJob > xJob( getMultiServiceFactory()->createInstance( "com.sun.star.text.MailMerge" ), uno::UNO_QUERY_THROW ); + mxJob.set( xJob ); + + int seq_id = 5; + if (tablename) seq_id += 2; + mSeqMailMergeArgs.realloc( seq_id ); + + seq_id = 0; + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_TYPE ), uno::Any( text::MailMergeType::SHELL ) ); + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DOCUMENT_URL ), uno::Any( + ( OUString(getURLFromSrc(mpTestDocumentPath) + OUString::createFromAscii(filename)) ) ) ); + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DATA_SOURCE_NAME ), uno::Any( aDBName ) ); + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_OUTPUT_URL ), uno::Any( aWorkDir ) ); + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_FILE_NAME_PREFIX ), uno::Any( aPrefix )); + if (tablename) + { + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND_TYPE ), uno::Any( sdb::CommandType::TABLE ) ); + mSeqMailMergeArgs[ seq_id++ ] = beans::NamedValue( OUString( UNO_NAME_DAD_COMMAND ), uno::Any( OUString::createFromAscii(tablename) ) ); + } + } + + virtual void executeMailMerge() + { + uno::Any res = mxJob->execute( mSeqMailMergeArgs ); + + OUString aCurOutputURL; + OUString aCurFileNamePrefix; + const beans::NamedValue *pArguments = mSeqMailMergeArgs.getConstArray(); + bool bOk = true; + sal_Int32 nArgs = mSeqMailMergeArgs.getLength(); + + for (sal_Int32 i = 0; i < nArgs; ++i) { + const OUString &rName = pArguments[i].Name; + const uno::Any &rValue = pArguments[i].Value; + + // all error checking was already done by the MM job execution + if (rName == UNO_NAME_OUTPUT_URL) + bOk &= rValue >>= aCurOutputURL; + else if (rName == UNO_NAME_FILE_NAME_PREFIX) + bOk &= rValue >>= aCurFileNamePrefix; + else if (rName == UNO_NAME_OUTPUT_TYPE) + bOk &= rValue >>= nCurOutputType; + } + + CPPUNIT_ASSERT(bOk); + + if (nCurOutputType == text::MailMergeType::SHELL) + { + CPPUNIT_ASSERT(res >>= mxMMComponent); + CPPUNIT_ASSERT(mxMMComponent.is()); + } + else + { + CPPUNIT_ASSERT(res == true); + mxMMComponent = loadFromDesktop( aCurOutputURL + "/" + aCurFileNamePrefix + "0.odt", + "com.sun.star.text.TextDocument"); + CPPUNIT_ASSERT(mxMMComponent.is()); + calcLayout(); + } + } }; /** diff --git a/sw/qa/extras/mailmerge/data/4_v01.ods b/sw/qa/extras/mailmerge/data/4_v01.ods new file mode 100644 index 000000000000..ffbf33bc2b91 Binary files /dev/null and b/sw/qa/extras/mailmerge/data/4_v01.ods differ diff --git a/sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odt b/sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odt new file mode 100644 index 000000000000..55a04364fe63 Binary files /dev/null and b/sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odt differ diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx new file mode 100644 index 000000000000..7c51b3fe66ff --- /dev/null +++ b/sw/qa/extras/mailmerge/mailmerge.cxx @@ -0,0 +1,76 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#if !defined(MACOSX) && !defined(WNT) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class MMTest : public SwModelTestBase +{ + public: + MMTest() : SwModelTestBase("/sw/qa/extras/mailmerge/data/", "writer8") {} +}; + +#define DECLARE_DFLT_MAILMERGE_TEST(TestName, filename, datasource, tablename) \ + DECLARE_MAILMERGE_TEST(TestName, filename, datasource, tablename, MMTest) + +DECLARE_DFLT_MAILMERGE_TEST(testMultiPageAnchoredDraws, "multiple-page-anchored-draws.odt", "4_v01.ods", "Tabelle1") +{ + executeMailMerge(); + + SwXTextDocument* pTxtDoc = dynamic_cast(mxMMComponent.get()); + CPPUNIT_ASSERT(pTxtDoc); + sal_uInt16 nPhysPages = pTxtDoc->GetDocShell()->GetWrtShell()->GetPhyPageNum(); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), nPhysPages); + + uno::Reference xDrawPageSupplier(mxMMComponent, uno::UNO_QUERY); + uno::Reference xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xDraws->getCount()); + + // bitset of all page numbers + char nPageSum = 0xFF; + uno::Reference xPropertySet; + + for (sal_Int32 i = 0; i < xDraws->getCount(); i++) + { + text::TextContentAnchorType nAnchorType; + sal_uInt16 nAnchorPageNo; + xPropertySet.set(xDraws->getByIndex(i), uno::UNO_QUERY); + + xPropertySet->getPropertyValue( UNO_NAME_ANCHOR_TYPE ) >>= nAnchorType; + CPPUNIT_ASSERT_EQUAL( text::TextContentAnchorType_AT_PAGE, nAnchorType ); + + xPropertySet->getPropertyValue( UNO_NAME_ANCHOR_PAGE_NO ) >>= nAnchorPageNo; + nPageSum &= !nAnchorPageNo; + } + + // are all shapes are on different page numbers? + CPPUNIT_ASSERT_EQUAL(char(0), nPageSum); +} + +#endif + +CPPUNIT_PLUGIN_IMPLEMENT(); +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit