summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2014-09-23 10:00:13 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2014-10-01 10:32:42 +0200
commitd10f6d49b77dcf955629901937d8d5e3a2976a6c (patch)
tree0946080bb6dcb4c537424bfd39c58ded2edd549c
parent5187ce45b93e5e841e541eac98da3fa2110fe632 (diff)
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
-rw-r--r--sw/CppunitTest_sw_mailmerge.mk93
-rw-r--r--sw/Module_sw.mk1
-rw-r--r--sw/qa/extras/inc/swmodeltestbase.hxx161
-rw-r--r--sw/qa/extras/mailmerge/data/4_v01.odsbin0 -> 18847 bytes
-rw-r--r--sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odtbin0 -> 9257 bytes
-rw-r--r--sw/qa/extras/mailmerge/mailmerge.cxx76
6 files changed, 329 insertions, 2 deletions
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 <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <com/sun/star/table/XCell.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/task/XJob.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/text/MailMergeType.hpp>
#include <test/bootstrapfixture.hxx>
#include <test/xmltesttools.hxx>
@@ -34,6 +39,8 @@
#include <comphelper/processfactory.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/mediadescriptor.hxx>
+#include <dbmgr.hxx>
+#include <unoprnms.hxx>
#include <unotxdoc.hxx>
#include <docsh.hxx>
@@ -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<OUString, OUString> 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<lang::XComponent> 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<SwXTextDocument *>(mxMMComponent.get());
+ pTxtDoc->GetDocShell()->DoClose();
+ }
+ else
+ mxMMComponent->dispose();
+ }
test::BootstrapFixture::tearDown();
}
@@ -259,6 +307,32 @@ protected:
}
/**
+ * 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
*/
virtual void verify()
@@ -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
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/4_v01.ods
Binary files 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
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/multiple-page-anchored-draws.odt
Binary files 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 <swmodeltestbase.hxx>
+
+#if !defined(MACOSX) && !defined(WNT)
+
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/style/PageStyleLayout.hpp>
+#include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/BorderLine.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/MailMergeType.hpp>
+#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+
+#include <wrtsh.hxx>
+#include <ndtxt.hxx>
+#include <swdtflvr.hxx>
+#include <view.hxx>
+#include <edtwin.hxx>
+#include <olmenu.hxx>
+#include <cmdid.h>
+
+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<SwXTextDocument *>(mxMMComponent.get());
+ CPPUNIT_ASSERT(pTxtDoc);
+ sal_uInt16 nPhysPages = pTxtDoc->GetDocShell()->GetWrtShell()->GetPhyPageNum();
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), nPhysPages);
+
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxMMComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xDraws->getCount());
+
+ // bitset of all page numbers
+ char nPageSum = 0xFF;
+ uno::Reference<beans::XPropertySet> 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: */