1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "sdmodeltestbase.hxx"
12 #include <svl/stritem.hxx>
13 #include <editeng/editobj.hxx>
14 #include <editeng/outlobj.hxx>
15 #include <editeng/ulspitem.hxx>
16 #include <editeng/fhgtitem.hxx>
17 #include <editeng/escapementitem.hxx>
19 #include <svx/svdotext.hxx>
20 #include <animations/animationnodehelper.hxx>
22 #include <com/sun/star/drawing/XDrawPage.hpp>
23 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
24 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
25 #include <com/sun/star/animations/XAnimationNode.hpp>
26 #include <com/sun/star/animations/XAnimate.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/chart/XChartDocument.hpp>
29 #include <com/sun/star/chart2/XChartDocument.hpp>
30 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
31 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
32 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
33 #include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
34 #include <com/sun/star/chart2/data/XDataSequence.hpp>
35 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
37 using namespace ::com::sun::star
;
39 /// Impress import filters tests.
40 class SdFiltersTest
: public SdModelTestBase
43 void testDocumentLayout();
51 CPPUNIT_TEST_SUITE(SdFiltersTest
);
52 CPPUNIT_TEST(testDocumentLayout
);
53 CPPUNIT_TEST(testSmoketest
);
54 CPPUNIT_TEST(testN759180
);
55 CPPUNIT_TEST(testN778859
);
56 CPPUNIT_TEST(testFdo64512
);
57 CPPUNIT_TEST(testFdo71075
);
58 CPPUNIT_TEST(testN828390
);
60 CPPUNIT_TEST_SUITE_END();
63 /** Test document against a reference XML dump of shapes.
65 If you want to update one of these tests, or add a new one, set the nUpdateMe
66 to the index of the test, and the dump XML's will be created (or rewritten)
67 instead of checking. Use with care - when the test is failing, first find out
68 why, instead of just updating .xml's blindly.
70 Example: Let's say you are adding a test called fdoABCD.pptx. You'll place it
71 to the data/ subdirectory, and will add an entry to aFilesToCompare below,
72 the 3rd parameter is for export test - can be -1 (don't export), ODP, PPT or PPTX
75 { "fdoABCD.pptx", "xml/fdoABCD_", PPTX },
77 and will count the index in the aFilesToCompare structure (1st is 0, 2nd is 1,
78 etc.) Temporarily you'll set nUpdateMe to this index (instead of -1), and run
82 This will generate the sd/qa/unit/data/xml/fdoABCD_*.xml for you. Now you
83 will change nUpdateMe back to -1, and commit your fdoABCD.pptx test, the
84 xml/fdoABCD_*.xml dumps, and the aFilesToCompare addition in one commit.
86 As the last step, you will revert your fix and do 'make sd' again, to check
87 that without your fix, the unit test breaks. Then clean up, and push :-)
89 NOTE: This approach is suitable only for tests of fixes that actually change
90 the layout - best to check by reverting your fix locally after having added
91 the test, and re-running; it should break.
93 void SdFiltersTest::testDocumentLayout()
95 struct { const char *pInput
, *pDump
; sal_Int32 nExportType
; } aFilesToCompare
[] =
97 { "odp/shapes-test.odp", "xml/shapes-test_page", -1 },
98 { "pptx/fdo47434-all.pptx", "pptx/xml/fdo47434_page", -1 },
99 { "n758621.ppt", "xml/n758621_", -1 },
100 { "fdo64586.ppt", "xml/fdo64586_", -1 },
101 { "n819614.pptx", "xml/n819614_", -1 },
102 { "n820786.pptx", "xml/n820786_", -1 },
103 { "n762695.pptx", "xml/n762695_", -1 },
104 { "n593612.pptx", "xml/n593612_", -1 },
105 // { "pptx/n828390.pptx", "pptx/xml/n828390_", PPTX }, // Example
108 for ( int i
= 0; i
< static_cast< int >( SAL_N_ELEMENTS( aFilesToCompare
) ); ++i
)
110 int nUpdateMe
= -1; // index of test we want to update; supposedly only when the test is created
112 ::sd::DrawDocShellRef xDocShRef
= loadURL( getURLFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare
[i
].pInput
) );
113 if( aFilesToCompare
[i
].nExportType
>= 0 )
114 xDocShRef
= saveAndReload( xDocShRef
, aFilesToCompare
[i
].nExportType
);
115 compareWithShapesDump( xDocShRef
,
116 getPathFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare
[i
].pDump
),
121 void SdFiltersTest::testSmoketest()
123 ::sd::DrawDocShellRef xDocShRef
= loadURL(getURLFromSrc("/sd/qa/unit/data/smoketest.pptx"));
124 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
125 CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef
->IsInDestruction() );
127 SdDrawDocument
*pDoc
= xDocShRef
->GetDoc();
128 CPPUNIT_ASSERT_MESSAGE( "no document", pDoc
!= NULL
);
130 // cf. SdrModel svx/svdmodel.hxx ...
132 CPPUNIT_ASSERT_MESSAGE( "wrong page count", pDoc
->GetPageCount() == 3);
134 const SdrPage
*pPage
= pDoc
->GetPage (1);
135 CPPUNIT_ASSERT_MESSAGE( "no page", pPage
!= NULL
);
137 sal_uIntPtr nObjs
= pPage
->GetObjCount();
138 for (sal_uIntPtr i
= 0; i
< nObjs
; i
++)
140 SdrObject
*pObj
= pPage
->GetObj(i
);
141 SdrObjKind eKind
= (SdrObjKind
) pObj
->GetObjIdentifier();
142 SdrTextObj
*pTxt
= dynamic_cast<SdrTextObj
*>( pObj
);
143 (void)pTxt
; (void)eKind
;
146 CPPUNIT_ASSERT_MESSAGE( "changed", !pDoc
->IsChanged() );
147 xDocShRef
->DoClose();
150 void SdFiltersTest::testN759180()
152 ::sd::DrawDocShellRef xDocShRef
= loadURL(getURLFromSrc("/sd/qa/unit/data/n759180.pptx"));
153 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
154 CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef
->IsInDestruction() );
156 SdDrawDocument
*pDoc
= xDocShRef
->GetDoc();
157 CPPUNIT_ASSERT_MESSAGE( "no document", pDoc
!= NULL
);
158 const SdrPage
*pPage
= pDoc
->GetPage (1);
159 CPPUNIT_ASSERT_MESSAGE( "no page", pPage
!= NULL
);
161 //sal_uIntPtr nObjs = pPage->GetObjCount();
162 //for (sal_uIntPtr i = 0; i < nObjs; i++)
165 SdrObject
*pObj
= pPage
->GetObj(0);
166 SdrTextObj
*pTxtObj
= dynamic_cast<SdrTextObj
*>( pObj
);
167 CPPUNIT_ASSERT(pTxtObj
);
168 std::vector
<EECharAttrib
> rLst
;
169 const EditTextObject
& aEdit
= pTxtObj
->GetOutlinerParaObject()->GetTextObject();
170 const SvxULSpaceItem
*pULSpace
= dynamic_cast<const SvxULSpaceItem
*>(aEdit
.GetParaAttribs(0).GetItem(EE_PARA_ULSPACE
));
171 CPPUNIT_ASSERT(pULSpace
);
172 CPPUNIT_ASSERT_MESSAGE( "Para bottom spacing is wrong!", pULSpace
->GetLower() == 0 );
173 aEdit
.GetCharAttribs(1, rLst
);
174 for( std::vector
<EECharAttrib
>::reverse_iterator it
= rLst
.rbegin(); it
!=rLst
.rend(); ++it
)
176 const SvxFontHeightItem
* pFontHeight
= dynamic_cast<const SvxFontHeightItem
*>((*it
).pAttr
);
180 // font height = 5 => 5*2540/72
181 CPPUNIT_ASSERT_MESSAGE( "Font height is wrong", pFontHeight
->GetHeight() == 176 );
188 void SdFiltersTest::testN828390()
190 bool bPassed
= false;
191 ::sd::DrawDocShellRef xDocShRef
= loadURL( getURLFromSrc("/sd/qa/unit/data/pptx/n828390.pptx") );
192 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
194 xDocShRef
= saveAndReload( xDocShRef
, PPTX
);
195 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
196 CPPUNIT_ASSERT_MESSAGE( "in destruction", !xDocShRef
->IsInDestruction() );
198 SdDrawDocument
*pDoc
= xDocShRef
->GetDoc();
199 CPPUNIT_ASSERT_MESSAGE( "no document", pDoc
!= NULL
);
200 const SdrPage
*pPage
= pDoc
->GetPage(1);
201 CPPUNIT_ASSERT_MESSAGE( "no page", pPage
!= NULL
);
203 std::vector
<EECharAttrib
> rLst
;
205 SdrObject
*pObj
= pPage
->GetObj(0);
206 SdrTextObj
*pTxtObj
= dynamic_cast<SdrTextObj
*>( pObj
);
207 const EditTextObject
& aEdit
= pTxtObj
->GetOutlinerParaObject()->GetTextObject();
208 aEdit
.GetCharAttribs(0, rLst
);
209 for( std::vector
<EECharAttrib
>::reverse_iterator it
= rLst
.rbegin(); it
!=rLst
.rend(); ++it
)
211 const SvxEscapementItem
*pFontEscapement
= dynamic_cast<const SvxEscapementItem
*>((*it
).pAttr
);
214 if( pFontEscapement
->GetEsc() == -25 )
222 CPPUNIT_ASSERT_MESSAGE("Subscript not exported properly", bPassed
);
225 void SdFiltersTest::testN778859()
227 ::sd::DrawDocShellRef xDocShRef
= loadURL(getURLFromSrc("/sd/qa/unit/data/pptx/n778859.pptx"));
228 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
229 CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef
->IsInDestruction() );
231 SdDrawDocument
*pDoc
= xDocShRef
->GetDoc();
232 CPPUNIT_ASSERT_MESSAGE( "no document", pDoc
!= NULL
);
233 const SdrPage
*pPage
= pDoc
->GetPage(1);
234 CPPUNIT_ASSERT_MESSAGE( "no page", pPage
!= NULL
);
237 SdrObject
*pObj
= pPage
->GetObj(1);
238 SdrTextObj
*pTxtObj
= dynamic_cast<SdrTextObj
*>( pObj
);
239 CPPUNIT_ASSERT(!pTxtObj
->IsAutoFit());
243 void SdFiltersTest::testFdo64512()
245 ::sd::DrawDocShellRef xDocShRef
= loadURL(getURLFromSrc("/sd/qa/unit/data/fdo64512.odp"));
246 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
247 CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef
->IsInDestruction() );
249 uno::Reference
< drawing::XDrawPagesSupplier
> xDoc(
250 xDocShRef
->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW
);
251 CPPUNIT_ASSERT_MESSAGE( "not exactly one page", xDoc
->getDrawPages()->getCount() == 1 );
253 uno::Reference
< drawing::XDrawPage
> xPage(
254 xDoc
->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW
);
255 CPPUNIT_ASSERT_MESSAGE( "no exactly three shapes", xPage
->getCount() == 3 );
257 uno::Reference
< beans::XPropertySet
> xConnectorShape(
258 xPage
->getByIndex(2), uno::UNO_QUERY
);
259 CPPUNIT_ASSERT_MESSAGE( "no connector shape", xConnectorShape
.is() );
261 uno::Reference
< beans::XPropertySet
> xSvgShape(
262 xConnectorShape
->getPropertyValue("StartShape"), uno::UNO_QUERY
);
263 CPPUNIT_ASSERT_MESSAGE( "no start shape", xSvgShape
.is() );
265 uno::Reference
< beans::XPropertySet
> xCustomShape(
266 xConnectorShape
->getPropertyValue("EndShape"), uno::UNO_QUERY
);
267 CPPUNIT_ASSERT_MESSAGE( "no end shape", xCustomShape
.is() );
269 uno::Reference
< animations::XAnimationNodeSupplier
> xAnimNodeSupplier(
270 xPage
, uno::UNO_QUERY_THROW
);
271 uno::Reference
< animations::XAnimationNode
> xRootNode(
272 xAnimNodeSupplier
->getAnimationNode() );
273 std::vector
< uno::Reference
< animations::XAnimationNode
> > aAnimVector
;
274 anim::create_deep_vector(xRootNode
, aAnimVector
);
275 CPPUNIT_ASSERT_MESSAGE( "not 8 animation nodes", aAnimVector
.size() == 8 );
277 uno::Reference
< animations::XAnimate
> xNode(
278 aAnimVector
[7], uno::UNO_QUERY_THROW
);
279 uno::Reference
< drawing::XShape
> xTargetShape(
280 xNode
->getTarget(), uno::UNO_QUERY_THROW
);
281 CPPUNIT_ASSERT_MESSAGE( "inner node not referencing svg shape",
282 xTargetShape
!= xSvgShape
);
285 // Unit test for importing charts
286 void SdFiltersTest::testFdo71075()
288 double values
[] = { 12.0, 13.0, 14.0 };
289 ::com::sun::star::uno::Any aAny
;
290 ::sd::DrawDocShellRef xDocShRef
= loadURL(getURLFromSrc("/sd/qa/unit/data/fdo71075.odp"));
291 CPPUNIT_ASSERT_MESSAGE( "failed to load", xDocShRef
.Is() );
292 CPPUNIT_ASSERT_MESSAGE( "not in destruction", !xDocShRef
->IsInDestruction() );
294 SdDrawDocument
*pDoc
= xDocShRef
->GetDoc();
295 CPPUNIT_ASSERT_MESSAGE( "no document", pDoc
!= NULL
);
296 uno::Reference
< drawing::XDrawPagesSupplier
> xDoc(xDocShRef
->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW
);
297 uno::Reference
< drawing::XDrawPage
> xPage(xDoc
->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW
);
298 uno::Reference
< drawing::XShape
> xShape(xPage
->getByIndex(0), uno::UNO_QUERY_THROW
);
299 CPPUNIT_ASSERT_MESSAGE( "failed to load shape", xShape
.is() );
301 uno::Reference
< beans::XPropertySet
> xPropSet( xShape
, uno::UNO_QUERY
);
302 aAny
= xPropSet
->getPropertyValue( OUString("Model") );
303 CPPUNIT_ASSERT_MESSAGE( "failed to load shape", aAny
.hasValue() );
305 uno::Reference
< chart::XChartDocument
> xChartDoc
;
307 CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChartDoc
.is() );
308 uno::Reference
< chart2::XChartDocument
> xChart2Doc( xChartDoc
, uno::UNO_QUERY
);
309 CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChart2Doc
.is() );
311 uno::Reference
< chart2::XCoordinateSystemContainer
> xBCooSysCnt( xChart2Doc
->getFirstDiagram(), uno::UNO_QUERY
);
312 uno::Sequence
< uno::Reference
< chart2::XCoordinateSystem
> > aCooSysSeq( xBCooSysCnt
->getCoordinateSystems());
313 uno::Reference
< chart2::XChartTypeContainer
> xCTCnt( aCooSysSeq
[0], uno::UNO_QUERY
);
315 uno::Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCTCnt
->getChartTypes()[0], uno::UNO_QUERY
);
316 CPPUNIT_ASSERT_MESSAGE( "failed to load data series", xDSCnt
.is() );
317 uno::Sequence
< uno::Reference
< chart2::XDataSeries
> > aSeriesSeq( xDSCnt
->getDataSeries());
318 CPPUNIT_ASSERT_MESSAGE( "Invalid Series count", aSeriesSeq
.getLength() == 1);
319 uno::Reference
< chart2::data::XDataSource
> xSource( aSeriesSeq
[0], uno::UNO_QUERY
);
320 uno::Sequence
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aSeqCnt(xSource
->getDataSequences());
321 CPPUNIT_ASSERT_MESSAGE( "Invalid Series count", aSeqCnt
.getLength() == 1);
322 uno::Reference
< chart2::data::XDataSequence
> xValueSeq( aSeqCnt
[0]->getValues() );
323 CPPUNIT_ASSERT_MESSAGE( "Invalid Data count", xValueSeq
->getData().getLength() == sizeof(values
)/(sizeof(double)));
324 uno::Reference
< chart2::data::XNumericalDataSequence
> xNumSeq( xValueSeq
, uno::UNO_QUERY
);
325 uno::Sequence
< double > aValues( xNumSeq
->getNumericalData());
326 for(sal_Int32 i
=0;i
<xValueSeq
->getData().getLength();i
++)
327 CPPUNIT_ASSERT_MESSAGE( "Invalid Series count", aValues
.getConstArray()[i
] == values
[i
]);
330 CPPUNIT_TEST_SUITE_REGISTRATION(SdFiltersTest
);
332 CPPUNIT_PLUGIN_IMPLEMENT();
334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */